Skip to content

Commit 374cfb1

Browse files
committed
Avoid follow-up errors if the number of generic parameters already doesn't match
1 parent 979f79d commit 374cfb1

34 files changed

+317
-543
lines changed

compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,13 @@ pub struct GenericArgCountResult {
231231
pub correct: Result<(), GenericArgCountMismatch>,
232232
}
233233

234+
impl GenericArgCountResult {
235+
fn error_reported(&self) -> Option<ErrorGuaranteed> {
236+
let err = self.correct.as_ref().err()?;
237+
err.reported
238+
}
239+
}
240+
234241
/// A context which can lower HIR's [`GenericArg`] to `rustc_middle`'s [`ty::GenericArg`].
235242
///
236243
/// Its only consumer is [`generics::lower_generic_args`].
@@ -403,9 +410,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
403410
self_ty.is_some(),
404411
);
405412

406-
if let Err(err) = &arg_count.correct
407-
&& let Some(reported) = err.reported
408-
{
413+
if let Some(reported) = arg_count.error_reported() {
409414
self.set_tainted_by_errors(reported);
410415
}
411416

@@ -601,6 +606,21 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
601606
&mut args_ctx,
602607
);
603608

609+
if let Some(guar) = arg_count.error_reported() {
610+
return (
611+
tcx.mk_args_from_iter(args.iter().map(|arg| match arg.unpack() {
612+
GenericArgKind::Lifetime(_) => {
613+
ty::GenericArg::from(ty::Region::new_error(tcx, guar))
614+
}
615+
GenericArgKind::Type(_) => Ty::new_error(tcx, guar).into(),
616+
GenericArgKind::Const(_) => {
617+
ty::Const::new_error(tcx, guar, Ty::new_error(tcx, guar)).into()
618+
}
619+
})),
620+
arg_count,
621+
);
622+
}
623+
604624
(args, arg_count)
605625
}
606626

compiler/rustc_hir_analysis/src/hir_ty_lowering/object_safety.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@ use rustc_hir::def_id::DefId;
88
use rustc_lint_defs::builtin::UNUSED_ASSOCIATED_TYPE_BOUNDS;
99
use rustc_middle::span_bug;
1010
use rustc_middle::ty::fold::BottomUpFolder;
11-
use rustc_middle::ty::{self, ExistentialPredicateStableCmpExt as _, Ty, TyCtxt, TypeFoldable};
11+
use rustc_middle::ty::{
12+
self, ExistentialPredicateStableCmpExt as _, Ty, TyCtxt, TypeFoldable, TypeVisitableExt,
13+
};
1214
use rustc_middle::ty::{DynKind, Upcast};
1315
use rustc_span::{ErrorGuaranteed, Span};
1416
use rustc_trait_selection::traits::error_reporting::report_object_safety_error;
@@ -214,7 +216,9 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
214216
// Erase the `dummy_self` (`trait_object_dummy_self`) used above.
215217
let existential_trait_refs = regular_traits.iter().map(|i| {
216218
i.trait_ref().map_bound(|trait_ref: ty::TraitRef<'tcx>| {
217-
assert_eq!(trait_ref.self_ty(), dummy_self);
219+
if !trait_ref.self_ty().references_error() {
220+
assert_eq!(trait_ref.self_ty(), dummy_self);
221+
}
218222

219223
// Verify that `dummy_self` did not leak inside default type parameters. This
220224
// could not be done at path creation, since we need to see through trait aliases.
@@ -281,7 +285,9 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
281285

282286
let existential_projections = projection_bounds.iter().map(|(bound, _)| {
283287
bound.map_bound(|mut b| {
284-
assert_eq!(b.projection_term.self_ty(), dummy_self);
288+
if !b.projection_term.self_ty().references_error() {
289+
assert_eq!(b.projection_term.self_ty(), dummy_self);
290+
}
285291

286292
// Like for trait refs, verify that `dummy_self` did not leak inside default type
287293
// parameters.

tests/ui/const-generics/adt_const_params/transmutable-ice-110969.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ fn via_associated_const() {
2424
trait Trait {
2525
const FALSE: bool = assert::is_transmutable::<Src, Dst, Context, {}>();
2626
//~^ ERROR mismatched types
27-
//~| ERROR `Src` cannot be safely transmuted into `Dst`
2827
//~| ERROR mismatched types
2928
}
3029
}

tests/ui/const-generics/adt_const_params/transmutable-ice-110969.stderr

Lines changed: 2 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -12,28 +12,13 @@ error[E0308]: mismatched types
1212
LL | const FALSE: bool = assert::is_transmutable::<Src, Dst, Context, {}>();
1313
| ^^ expected `Assume`, found `()`
1414

15-
error[E0277]: `Src` cannot be safely transmuted into `Dst`
16-
--> $DIR/transmutable-ice-110969.rs:25:60
17-
|
18-
LL | const FALSE: bool = assert::is_transmutable::<Src, Dst, Context, {}>();
19-
| ^^^ `Dst` may carry safety invariants
20-
|
21-
note: required by a bound in `is_transmutable`
22-
--> $DIR/transmutable-ice-110969.rs:11:14
23-
|
24-
LL | pub fn is_transmutable<Src, Dst, Context, const ASSUME: std::mem::Assume>()
25-
| --------------- required by a bound in this function
26-
LL | where
27-
LL | Dst: BikeshedIntrinsicFrom<Src, Context, ASSUME>,
28-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `is_transmutable`
29-
3015
error[E0308]: mismatched types
3116
--> $DIR/transmutable-ice-110969.rs:25:29
3217
|
3318
LL | const FALSE: bool = assert::is_transmutable::<Src, Dst, Context, {}>();
3419
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `bool`, found `()`
3520

36-
error: aborting due to 4 previous errors
21+
error: aborting due to 3 previous errors
3722

38-
Some errors have detailed explanations: E0107, E0277, E0308.
23+
Some errors have detailed explanations: E0107, E0308.
3924
For more information about an error, try `rustc --explain E0107`.

tests/ui/consts/fn_trait_refs.stderr

Lines changed: 66 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,12 @@ LL | T: ~const Fn<()> + ~const Destruct,
1818
|
1919
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
2020

21+
error[E0220]: associated type `Output` not found for `T`
22+
--> $DIR/fn_trait_refs.rs:13:35
23+
|
24+
LL | const fn tester_fn<T>(f: T) -> T::Output
25+
| ^^^^^^ associated type `Output` not found
26+
2127
error: `~const` can only be applied to `#[const_trait]` traits
2228
--> $DIR/fn_trait_refs.rs:22:15
2329
|
@@ -32,6 +38,12 @@ LL | T: ~const FnMut<()> + ~const Destruct,
3238
|
3339
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
3440

41+
error[E0220]: associated type `Output` not found for `T`
42+
--> $DIR/fn_trait_refs.rs:20:43
43+
|
44+
LL | const fn tester_fn_mut<T>(mut f: T) -> T::Output
45+
| ^^^^^^ associated type `Output` not found
46+
3547
error: `~const` can only be applied to `#[const_trait]` traits
3648
--> $DIR/fn_trait_refs.rs:29:15
3749
|
@@ -46,6 +58,12 @@ LL | T: ~const FnOnce<()>,
4658
|
4759
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
4860

61+
error[E0220]: associated type `Output` not found for `T`
62+
--> $DIR/fn_trait_refs.rs:27:40
63+
|
64+
LL | const fn tester_fn_once<T>(f: T) -> T::Output
65+
| ^^^^^^ associated type `Output` not found
66+
4967
error: `~const` can only be applied to `#[const_trait]` traits
5068
--> $DIR/fn_trait_refs.rs:36:15
5169
|
@@ -60,6 +78,24 @@ LL | T: ~const Fn<()> + ~const Destruct,
6078
|
6179
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
6280

81+
error[E0220]: associated type `Output` not found for `T`
82+
--> $DIR/fn_trait_refs.rs:34:38
83+
|
84+
LL | const fn test_fn<T>(mut f: T) -> (T::Output, T::Output, T::Output)
85+
| ^^^^^^ associated type `Output` not found
86+
87+
error[E0220]: associated type `Output` not found for `T`
88+
--> $DIR/fn_trait_refs.rs:34:49
89+
|
90+
LL | const fn test_fn<T>(mut f: T) -> (T::Output, T::Output, T::Output)
91+
| ^^^^^^ associated type `Output` not found
92+
93+
error[E0220]: associated type `Output` not found for `T`
94+
--> $DIR/fn_trait_refs.rs:34:60
95+
|
96+
LL | const fn test_fn<T>(mut f: T) -> (T::Output, T::Output, T::Output)
97+
| ^^^^^^ associated type `Output` not found
98+
6399
error: `~const` can only be applied to `#[const_trait]` traits
64100
--> $DIR/fn_trait_refs.rs:50:15
65101
|
@@ -74,115 +110,52 @@ LL | T: ~const FnMut<()> + ~const Destruct,
74110
|
75111
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
76112

77-
error[E0015]: cannot call non-const operator in constants
78-
--> $DIR/fn_trait_refs.rs:72:17
79-
|
80-
LL | assert!(test_one == (1, 1, 1));
81-
| ^^^^^^^^^^^^^^^^^^^^^
82-
|
83-
= note: calls in constants are limited to constant functions, tuple structs and tuple variants
84-
help: add `#![feature(effects)]` to the crate attributes to enable
85-
|
86-
LL + #![feature(effects)]
113+
error[E0220]: associated type `Output` not found for `T`
114+
--> $DIR/fn_trait_refs.rs:48:42
87115
|
116+
LL | const fn test_fn_mut<T>(mut f: T) -> (T::Output, T::Output)
117+
| ^^^^^^ associated type `Output` not found
88118

89-
error[E0015]: cannot call non-const operator in constants
90-
--> $DIR/fn_trait_refs.rs:75:17
91-
|
92-
LL | assert!(test_two == (2, 2));
93-
| ^^^^^^^^^^^^^^^^^^
94-
|
95-
= note: calls in constants are limited to constant functions, tuple structs and tuple variants
96-
help: add `#![feature(effects)]` to the crate attributes to enable
97-
|
98-
LL + #![feature(effects)]
119+
error[E0220]: associated type `Output` not found for `T`
120+
--> $DIR/fn_trait_refs.rs:48:53
99121
|
122+
LL | const fn test_fn_mut<T>(mut f: T) -> (T::Output, T::Output)
123+
| ^^^^^^ associated type `Output` not found
100124

101-
error[E0015]: cannot call non-const closure in constant functions
125+
error[E0618]: expected function, found `T`
102126
--> $DIR/fn_trait_refs.rs:17:5
103127
|
104-
LL | f()
105-
| ^^^
106-
|
107-
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
108-
help: consider further restricting this bound
109-
|
110-
LL | T: ~const Fn<()> + ~const Destruct + ~const std::ops::Fn<()>,
111-
| +++++++++++++++++++++++++
112-
help: add `#![feature(effects)]` to the crate attributes to enable
113-
|
114-
LL + #![feature(effects)]
115-
|
116-
117-
error[E0493]: destructor of `T` cannot be evaluated at compile-time
118-
--> $DIR/fn_trait_refs.rs:13:23
119-
|
120128
LL | const fn tester_fn<T>(f: T) -> T::Output
121-
| ^ the destructor for this type cannot be evaluated in constant functions
129+
| - `f` has type `T`
122130
...
123-
LL | }
124-
| - value is dropped here
125-
126-
error[E0015]: cannot call non-const closure in constant functions
127-
--> $DIR/fn_trait_refs.rs:24:5
128-
|
129131
LL | f()
130-
| ^^^
131-
|
132-
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
133-
help: consider further restricting this bound
134-
|
135-
LL | T: ~const FnMut<()> + ~const Destruct + ~const std::ops::FnMut<()>,
136-
| ++++++++++++++++++++++++++++
137-
help: add `#![feature(effects)]` to the crate attributes to enable
138-
|
139-
LL + #![feature(effects)]
140-
|
132+
| ^--
133+
| |
134+
| call expression requires function
141135

142-
error[E0493]: destructor of `T` cannot be evaluated at compile-time
143-
--> $DIR/fn_trait_refs.rs:20:27
136+
error[E0618]: expected function, found `T`
137+
--> $DIR/fn_trait_refs.rs:24:5
144138
|
145139
LL | const fn tester_fn_mut<T>(mut f: T) -> T::Output
146-
| ^^^^^ the destructor for this type cannot be evaluated in constant functions
140+
| ----- `f` has type `T`
147141
...
148-
LL | }
149-
| - value is dropped here
150-
151-
error[E0015]: cannot call non-const closure in constant functions
152-
--> $DIR/fn_trait_refs.rs:31:5
153-
|
154142
LL | f()
155-
| ^^^
156-
|
157-
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
158-
help: consider further restricting this bound
159-
|
160-
LL | T: ~const FnOnce<()> + ~const std::ops::FnOnce<()>,
161-
| +++++++++++++++++++++++++++++
162-
help: add `#![feature(effects)]` to the crate attributes to enable
163-
|
164-
LL + #![feature(effects)]
165-
|
143+
| ^--
144+
| |
145+
| call expression requires function
166146

167-
error[E0493]: destructor of `T` cannot be evaluated at compile-time
168-
--> $DIR/fn_trait_refs.rs:34:21
169-
|
170-
LL | const fn test_fn<T>(mut f: T) -> (T::Output, T::Output, T::Output)
171-
| ^^^^^ the destructor for this type cannot be evaluated in constant functions
172-
...
173-
LL | }
174-
| - value is dropped here
175-
176-
error[E0493]: destructor of `T` cannot be evaluated at compile-time
177-
--> $DIR/fn_trait_refs.rs:48:25
147+
error[E0618]: expected function, found `T`
148+
--> $DIR/fn_trait_refs.rs:31:5
178149
|
179-
LL | const fn test_fn_mut<T>(mut f: T) -> (T::Output, T::Output)
180-
| ^^^^^ the destructor for this type cannot be evaluated in constant functions
150+
LL | const fn tester_fn_once<T>(f: T) -> T::Output
151+
| - `f` has type `T`
181152
...
182-
LL | }
183-
| - value is dropped here
153+
LL | f()
154+
| ^--
155+
| |
156+
| call expression requires function
184157

185-
error: aborting due to 20 previous errors
158+
error: aborting due to 22 previous errors
186159

187-
Some errors have detailed explanations: E0015, E0493, E0635.
188-
For more information about an error, try `rustc --explain E0015`.
160+
Some errors have detailed explanations: E0220, E0618, E0635.
161+
For more information about an error, try `rustc --explain E0220`.

tests/ui/consts/unstable-const-fn-in-libcore.stderr

Lines changed: 8 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -4,41 +4,17 @@ error: `~const` can only be applied to `#[const_trait]` traits
44
LL | const fn unwrap_or_else<F: ~const FnOnce() -> T>(self, f: F) -> T {
55
| ^^^^^^^^^^^^^
66

7-
error[E0015]: cannot call non-const closure in constant functions
7+
error[E0618]: expected function, found `F`
88
--> $DIR/unstable-const-fn-in-libcore.rs:24:26
99
|
10-
LL | Opt::None => f(),
11-
| ^^^
12-
|
13-
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
14-
help: consider further restricting this bound
15-
|
16-
LL | const fn unwrap_or_else<F: ~const FnOnce() -> T + ~const std::ops::FnOnce<()>>(self, f: F) -> T {
17-
| +++++++++++++++++++++++++++++
18-
help: add `#![feature(effects)]` to the crate attributes to enable
19-
|
20-
LL + #![feature(effects)]
21-
|
22-
23-
error[E0493]: destructor of `F` cannot be evaluated at compile-time
24-
--> $DIR/unstable-const-fn-in-libcore.rs:19:60
25-
|
26-
LL | const fn unwrap_or_else<F: ~const FnOnce() -> T>(self, f: F) -> T {
27-
| ^ the destructor for this type cannot be evaluated in constant functions
28-
...
29-
LL | }
30-
| - value is dropped here
31-
32-
error[E0493]: destructor of `Opt<T>` cannot be evaluated at compile-time
33-
--> $DIR/unstable-const-fn-in-libcore.rs:19:54
34-
|
3510
LL | const fn unwrap_or_else<F: ~const FnOnce() -> T>(self, f: F) -> T {
36-
| ^^^^ the destructor for this type cannot be evaluated in constant functions
11+
| - `f` has type `F`
3712
...
38-
LL | }
39-
| - value is dropped here
13+
LL | Opt::None => f(),
14+
| ^--
15+
| |
16+
| call expression requires function
4017

41-
error: aborting due to 4 previous errors
18+
error: aborting due to 2 previous errors
4219

43-
Some errors have detailed explanations: E0015, E0493.
44-
For more information about an error, try `rustc --explain E0015`.
20+
For more information about this error, try `rustc --explain E0618`.

tests/ui/generic-associated-types/gat-trait-path-missing-lifetime.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ impl<T> X for T { //~ ERROR: not all trait items implemented
99
//~^ ERROR missing generics for associated type
1010
//~^^ ERROR missing generics for associated type
1111
//~| ERROR method `foo` has 1 type parameter but its trait declaration has 0 type parameters
12-
//~| ERROR may not live long enough
1312
t
1413
}
1514
}

0 commit comments

Comments
 (0)