Skip to content

Commit 1d657a5

Browse files
committed
Delegation: fix ICE on wrong instantiation
1 parent b13a71a commit 1d657a5

File tree

4 files changed

+99
-20
lines changed

4 files changed

+99
-20
lines changed

compiler/rustc_hir_analysis/messages.ftl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -292,7 +292,7 @@ hir_analysis_must_implement_not_function_span_note = required by this annotation
292292
hir_analysis_must_implement_one_of_attribute = the `#[rustc_must_implement_one_of]` attribute must be used with at least 2 args
293293
294294
hir_analysis_not_supported_delegation =
295-
{$descr} is not supported yet
295+
{$descr}
296296
.label = callee defined here
297297
298298
hir_analysis_only_current_traits_arbitrary = only traits defined in the current crate can be implemented for arbitrary types

compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs

Lines changed: 42 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ use crate::hir_ty_lowering::errors::prohibit_assoc_item_binding;
2626
use crate::hir_ty_lowering::generics::{check_generic_arg_count, lower_generic_args};
2727
use crate::middle::resolve_bound_vars as rbv;
2828
use crate::require_c_abi_if_c_variadic;
29+
use crate::rustc_middle::ty::TypeSuperVisitable;
2930
use rustc_ast::TraitObjectSyntax;
3031
use rustc_data_structures::fx::{FxHashSet, FxIndexMap};
3132
use rustc_errors::{
@@ -41,7 +42,7 @@ use rustc_infer::traits::ObligationCause;
4142
use rustc_middle::middle::stability::AllowUnstable;
4243
use rustc_middle::ty::{
4344
self, Const, GenericArgKind, GenericArgsRef, GenericParamDefKind, ParamEnv, Ty, TyCtxt,
44-
TypeVisitableExt,
45+
TypeVisitable, TypeVisitableExt,
4546
};
4647
use rustc_session::lint::builtin::AMBIGUOUS_ASSOCIATED_ITEMS;
4748
use rustc_span::edit_distance::find_best_match_for_name;
@@ -52,6 +53,7 @@ use rustc_trait_selection::traits::wf::object_region_bounds;
5253
use rustc_trait_selection::traits::{self, ObligationCtxt};
5354

5455
use std::fmt::Display;
56+
use std::ops::ControlFlow;
5557
use std::slice;
5658

5759
/// A path segment that is semantically allowed to have generic arguments.
@@ -2193,46 +2195,76 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
21932195
&& let hir::FnRetTy::Return(ty) = decl.output
21942196
&& let hir::TyKind::InferDelegation(_, _) = ty.kind
21952197
{
2196-
try_emit("recursive delegation");
2198+
try_emit("recursive delegation is not supported yet");
21972199
}
21982200

21992201
let sig = self.tcx().fn_sig(sig_id).instantiate_identity();
22002202
if sig.output().has_opaque_types() {
2201-
try_emit("delegation to a function with opaque type");
2203+
try_emit("delegation to a function with opaque type is not supported yet");
22022204
}
22032205

22042206
let sig_generics = self.tcx().generics_of(sig_id);
22052207
let parent = self.tcx().parent(self.item_def_id());
22062208
let parent_generics = self.tcx().generics_of(parent);
22072209

2208-
let parent_is_trait = (self.tcx().def_kind(parent) == DefKind::Trait) as usize;
2210+
let parent_def_kind = self.tcx().def_kind(parent);
2211+
let parent_is_trait = (parent_def_kind == DefKind::Trait) as usize;
22092212
let sig_has_self = sig_generics.has_self as usize;
22102213

22112214
if sig_generics.count() > sig_has_self || parent_generics.count() > parent_is_trait {
2212-
try_emit("delegation with early bound generics");
2215+
try_emit("delegation with early bound generics is not supported yet");
2216+
}
2217+
2218+
// There is no way to instantiate `Self` param for caller if
2219+
// 1. callee is a trait method && callee contains `Self` param
2220+
// 2. parent item isn't a trait or impl
2221+
if let DefKind::AssocFn = self.tcx().def_kind(sig_id)
2222+
&& !matches!(parent_def_kind, DefKind::Impl { .. } | DefKind::Trait)
2223+
&& self.tcx().associated_item(sig_id).container
2224+
== ty::AssocItemContainer::TraitContainer
2225+
{
2226+
struct HasSelfParamVisitor;
2227+
2228+
impl<'tcx> ty::TypeVisitor<TyCtxt<'tcx>> for HasSelfParamVisitor {
2229+
type Result = ControlFlow<()>;
2230+
2231+
fn visit_ty(&mut self, ty: Ty<'tcx>) -> Self::Result {
2232+
// All early bound generics except `Self` are previously banned.
2233+
// It is enough to check only the `ty::Param`.
2234+
if matches!(ty.kind(), ty::Param(..)) {
2235+
return ControlFlow::Break(());
2236+
}
2237+
2238+
ty.super_visit_with(self)
2239+
}
2240+
}
2241+
2242+
if sig.visit_with(&mut HasSelfParamVisitor).is_break() {
2243+
try_emit("Couldn't instantiate `Self` callee type");
2244+
}
22132245
}
22142246

22152247
if self.tcx().asyncness(sig_id) == ty::Asyncness::Yes {
2216-
try_emit("delegation to async functions");
2248+
try_emit("delegation to async functions is not supported yet");
22172249
}
22182250

22192251
if self.tcx().constness(sig_id) == hir::Constness::Const {
2220-
try_emit("delegation to const functions");
2252+
try_emit("delegation to const functions is not supported yet");
22212253
}
22222254

22232255
if sig.c_variadic() {
2224-
try_emit("delegation to variadic functions");
2256+
try_emit("delegation to variadic functions is not supported yet");
22252257
// variadic functions are also `unsafe` and `extern "C"`.
22262258
// Do not emit same error multiple times.
22272259
return error_occured;
22282260
}
22292261

22302262
if let hir::Unsafety::Unsafe = sig.unsafety() {
2231-
try_emit("delegation to unsafe functions");
2263+
try_emit("delegation to unsafe functions is not supported yet");
22322264
}
22332265

22342266
if abi::Abi::Rust != sig.abi() {
2235-
try_emit("delegation to non Rust ABI functions");
2267+
try_emit("delegation to non Rust ABI functions is not supported yet");
22362268
}
22372269

22382270
error_occured

tests/ui/delegation/not-supported.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,26 @@ mod generics {
6161
}
6262
}
6363

64+
mod generics_self_forbidden {
65+
trait Trait {
66+
fn foo1(&self, x: i32) -> i32 { 0 }
67+
fn foo2(_: Option<&Self>) {}
68+
fn foo3(_: i32) {}
69+
fn foo4(_: i32) {}
70+
}
71+
72+
struct S;
73+
impl Trait for S {}
74+
75+
reuse Trait::foo1;
76+
//~^ ERROR Couldn't instantiate `Self` callee type
77+
reuse Trait::foo2;
78+
//~^ ERROR Couldn't instantiate `Self` callee type
79+
reuse Trait::foo3;
80+
//~^ ERROR type annotations needed
81+
reuse <S as Trait>::foo4;
82+
}
83+
6484
mod opaque {
6585
trait Trait {}
6686
impl Trait for () {}

tests/ui/delegation/not-supported.stderr

Lines changed: 36 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -115,8 +115,26 @@ LL | fn foo2<T>(&self, x: T) -> T { x }
115115
LL | reuse Trait::foo2 { &self.0 }
116116
| ^^^^
117117

118+
error: Couldn't instantiate `Self` callee type
119+
--> $DIR/not-supported.rs:75:18
120+
|
121+
LL | fn foo1(&self, x: i32) -> i32 { 0 }
122+
| ----------------------------- callee defined here
123+
...
124+
LL | reuse Trait::foo1;
125+
| ^^^^
126+
127+
error: Couldn't instantiate `Self` callee type
128+
--> $DIR/not-supported.rs:77:18
129+
|
130+
LL | fn foo2(_: Option<&Self>) {}
131+
| ------------------------- callee defined here
132+
...
133+
LL | reuse Trait::foo2;
134+
| ^^^^
135+
118136
error: delegation with early bound generics is not supported yet
119-
--> $DIR/not-supported.rs:74:21
137+
--> $DIR/not-supported.rs:94:21
120138
|
121139
LL | pub fn opaque_arg(_: impl Trait) -> i32 { 0 }
122140
| --------------------------------------- callee defined here
@@ -125,7 +143,7 @@ LL | reuse to_reuse::opaque_arg;
125143
| ^^^^^^^^^^
126144

127145
error: delegation to a function with opaque type is not supported yet
128-
--> $DIR/not-supported.rs:76:21
146+
--> $DIR/not-supported.rs:96:21
129147
|
130148
LL | pub fn opaque_ret() -> impl Trait { unimplemented!() }
131149
| --------------------------------- callee defined here
@@ -134,7 +152,7 @@ LL | reuse to_reuse::opaque_ret;
134152
| ^^^^^^^^^^
135153

136154
error: delegation to unsafe functions is not supported yet
137-
--> $DIR/not-supported.rs:88:21
155+
--> $DIR/not-supported.rs:108:21
138156
|
139157
LL | pub unsafe fn unsafe_fn() {}
140158
| ------------------------- callee defined here
@@ -143,7 +161,7 @@ LL | reuse to_reuse::unsafe_fn;
143161
| ^^^^^^^^^
144162

145163
error: delegation to non Rust ABI functions is not supported yet
146-
--> $DIR/not-supported.rs:90:21
164+
--> $DIR/not-supported.rs:110:21
147165
|
148166
LL | pub extern "C" fn extern_fn() {}
149167
| ----------------------------- callee defined here
@@ -152,7 +170,7 @@ LL | reuse to_reuse::extern_fn;
152170
| ^^^^^^^^^
153171

154172
error: delegation to variadic functions is not supported yet
155-
--> $DIR/not-supported.rs:92:21
173+
--> $DIR/not-supported.rs:112:21
156174
|
157175
LL | pub unsafe extern "C" fn variadic_fn(n: usize, mut args: ...) {}
158176
| ------------------------------------------------------------- callee defined here
@@ -161,7 +179,7 @@ LL | reuse to_reuse::variadic_fn;
161179
| ^^^^^^^^^^^
162180

163181
error: delegation to const functions is not supported yet
164-
--> $DIR/not-supported.rs:94:21
182+
--> $DIR/not-supported.rs:114:21
165183
|
166184
LL | pub const fn const_fn() {}
167185
| ----------------------- callee defined here
@@ -170,15 +188,24 @@ LL | reuse to_reuse::const_fn;
170188
| ^^^^^^^^
171189

172190
error: recursive delegation is not supported yet
173-
--> $DIR/not-supported.rs:107:22
191+
--> $DIR/not-supported.rs:127:22
174192
|
175193
LL | pub reuse to_reuse2::foo;
176194
| --- callee defined here
177195
...
178196
LL | reuse to_reuse1::foo;
179197
| ^^^
180198

181-
error: aborting due to 19 previous errors; 1 warning emitted
199+
error[E0283]: type annotations needed
200+
--> $DIR/not-supported.rs:79:11
201+
|
202+
LL | reuse Trait::foo3;
203+
| ^^^^^^^^^^^ cannot infer type
204+
|
205+
= note: cannot satisfy `_: generics_self_forbidden::Trait`
206+
= help: the trait `generics_self_forbidden::Trait` is implemented for `generics_self_forbidden::S`
207+
208+
error: aborting due to 22 previous errors; 1 warning emitted
182209

183-
Some errors have detailed explanations: E0049, E0195.
210+
Some errors have detailed explanations: E0049, E0195, E0283.
184211
For more information about an error, try `rustc --explain E0049`.

0 commit comments

Comments
 (0)