Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 16d09fa

Browse files
committedMar 25, 2024
delegation: Support async, const, extern "ABI" and C-variadic functions
Also allow `impl Trait` in delegated functions. The delegation item will refer to the original opaque type from the callee, fresh opaque type won't be created.
1 parent 6312987 commit 16d09fa

File tree

11 files changed

+219
-161
lines changed

11 files changed

+219
-161
lines changed
 

‎compiler/rustc_ast_lowering/src/delegation.rs

Lines changed: 75 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ use rustc_errors::ErrorGuaranteed;
4949
use rustc_hir as hir;
5050
use rustc_hir::def_id::DefId;
5151
use rustc_middle::span_bug;
52-
use rustc_middle::ty::ResolverAstLowering;
52+
use rustc_middle::ty::{Asyncness, ResolverAstLowering};
5353
use rustc_span::{symbol::Ident, Span};
5454
use rustc_target::spec::abi;
5555
use std::iter;
@@ -67,7 +67,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
6767
return false;
6868
};
6969
if let Some(local_sig_id) = sig_id.as_local() {
70-
self.resolver.has_self.contains(&local_sig_id)
70+
self.resolver.delegation_fn_sigs[&local_sig_id].has_self
7171
} else {
7272
match self.tcx.def_kind(sig_id) {
7373
DefKind::Fn => false,
@@ -82,13 +82,14 @@ impl<'hir> LoweringContext<'_, 'hir> {
8282
delegation: &Delegation,
8383
item_id: NodeId,
8484
) -> DelegationResults<'hir> {
85-
let span = delegation.path.segments.last().unwrap().ident.span;
85+
let span = self.lower_span(delegation.path.segments.last().unwrap().ident.span);
8686
let sig_id = self.get_delegation_sig_id(item_id, delegation.id, span);
8787
match sig_id {
8888
Ok(sig_id) => {
89-
let decl = self.lower_delegation_decl(sig_id, span);
90-
let sig = self.lower_delegation_sig(span, decl);
91-
let body_id = self.lower_delegation_body(sig.decl, delegation);
89+
let (param_count, c_variadic) = self.param_count(sig_id);
90+
let decl = self.lower_delegation_decl(sig_id, param_count, c_variadic, span);
91+
let sig = self.lower_delegation_sig(sig_id, decl, span);
92+
let body_id = self.lower_delegation_body(delegation, param_count, span);
9293

9394
let generics = self.lower_delegation_generics(span);
9495
DelegationResults { body_id, sig, generics }
@@ -123,70 +124,92 @@ impl<'hir> LoweringContext<'_, 'hir> {
123124
})
124125
}
125126

127+
fn param_count(&self, sig_id: DefId) -> (usize, bool /*c_variadic*/) {
128+
if let Some(local_sig_id) = sig_id.as_local() {
129+
// Map may be filled incorrectly due to recursive delegation.
130+
// Error will be emmited later in astconv.
131+
match self.resolver.delegation_fn_sigs.get(&local_sig_id) {
132+
Some(sig) => (sig.param_count, sig.c_variadic),
133+
None => (0, false),
134+
}
135+
} else {
136+
let sig = self.tcx.fn_sig(sig_id).skip_binder().skip_binder();
137+
(sig.inputs().len(), sig.c_variadic)
138+
}
139+
}
140+
126141
fn lower_delegation_decl(
127142
&mut self,
128143
sig_id: DefId,
129-
param_span: Span,
144+
param_count: usize,
145+
c_variadic: bool,
146+
span: Span,
130147
) -> &'hir hir::FnDecl<'hir> {
131-
let args_count = if let Some(local_sig_id) = sig_id.as_local() {
132-
// Map may be filled incorrectly due to recursive delegation.
133-
// Error will be emitted later during HIR ty lowering.
134-
self.resolver.fn_parameter_counts.get(&local_sig_id).cloned().unwrap_or_default()
135-
} else {
136-
self.tcx.fn_arg_names(sig_id).len()
137-
};
138-
let inputs = self.arena.alloc_from_iter((0..args_count).map(|arg| hir::Ty {
148+
// The last parameter in C variadic functions is skipped in the signature,
149+
// like during regular lowering.
150+
let decl_param_count = param_count - c_variadic as usize;
151+
let inputs = self.arena.alloc_from_iter((0..decl_param_count).map(|arg| hir::Ty {
139152
hir_id: self.next_id(),
140153
kind: hir::TyKind::InferDelegation(sig_id, hir::InferDelegationKind::Input(arg)),
141-
span: self.lower_span(param_span),
154+
span,
142155
}));
143156

144157
let output = self.arena.alloc(hir::Ty {
145158
hir_id: self.next_id(),
146159
kind: hir::TyKind::InferDelegation(sig_id, hir::InferDelegationKind::Output),
147-
span: self.lower_span(param_span),
160+
span,
148161
});
149162

150163
self.arena.alloc(hir::FnDecl {
151164
inputs,
152165
output: hir::FnRetTy::Return(output),
153-
c_variadic: false,
166+
c_variadic,
154167
lifetime_elision_allowed: true,
155168
implicit_self: hir::ImplicitSelfKind::None,
156169
})
157170
}
158171

159172
fn lower_delegation_sig(
160173
&mut self,
161-
span: Span,
174+
sig_id: DefId,
162175
decl: &'hir hir::FnDecl<'hir>,
176+
span: Span,
163177
) -> hir::FnSig<'hir> {
164-
hir::FnSig {
165-
decl,
166-
header: hir::FnHeader {
167-
unsafety: hir::Unsafety::Normal,
168-
constness: hir::Constness::NotConst,
169-
asyncness: hir::IsAsync::NotAsync,
170-
abi: abi::Abi::Rust,
171-
},
172-
span: self.lower_span(span),
173-
}
178+
let header = if let Some(local_sig_id) = sig_id.as_local() {
179+
match self.resolver.delegation_fn_sigs.get(&local_sig_id) {
180+
Some(sig) => self.lower_fn_header(sig.header),
181+
None => self.generate_header_error(),
182+
}
183+
} else {
184+
let sig = self.tcx.fn_sig(sig_id).skip_binder().skip_binder();
185+
let asyncness = match self.tcx.asyncness(sig_id) {
186+
Asyncness::Yes => hir::IsAsync::Async(span),
187+
Asyncness::No => hir::IsAsync::NotAsync,
188+
};
189+
hir::FnHeader {
190+
unsafety: sig.unsafety,
191+
constness: self.tcx.constness(sig_id),
192+
asyncness,
193+
abi: sig.abi,
194+
}
195+
};
196+
hir::FnSig { decl, header, span }
174197
}
175198

176-
fn generate_param(&mut self, ty: &'hir hir::Ty<'hir>) -> (hir::Param<'hir>, NodeId) {
199+
fn generate_param(&mut self, span: Span) -> (hir::Param<'hir>, NodeId) {
177200
let pat_node_id = self.next_node_id();
178201
let pat_id = self.lower_node_id(pat_node_id);
179202
let pat = self.arena.alloc(hir::Pat {
180203
hir_id: pat_id,
181204
kind: hir::PatKind::Binding(hir::BindingAnnotation::NONE, pat_id, Ident::empty(), None),
182-
span: ty.span,
205+
span,
183206
default_binding_modes: false,
184207
});
185208

186-
(hir::Param { hir_id: self.next_id(), pat, ty_span: ty.span, span: ty.span }, pat_node_id)
209+
(hir::Param { hir_id: self.next_id(), pat, ty_span: span, span }, pat_node_id)
187210
}
188211

189-
fn generate_arg(&mut self, ty: &'hir hir::Ty<'hir>, param_id: HirId) -> hir::Expr<'hir> {
212+
fn generate_arg(&mut self, param_id: HirId, span: Span) -> hir::Expr<'hir> {
190213
let segments = self.arena.alloc_from_iter(iter::once(hir::PathSegment {
191214
ident: Ident::empty(),
192215
hir_id: self.next_id(),
@@ -195,20 +218,20 @@ impl<'hir> LoweringContext<'_, 'hir> {
195218
infer_args: false,
196219
}));
197220

198-
let path =
199-
self.arena.alloc(hir::Path { span: ty.span, res: Res::Local(param_id), segments });
221+
let path = self.arena.alloc(hir::Path { span, res: Res::Local(param_id), segments });
200222

201223
hir::Expr {
202224
hir_id: self.next_id(),
203225
kind: hir::ExprKind::Path(hir::QPath::Resolved(None, path)),
204-
span: ty.span,
226+
span,
205227
}
206228
}
207229

208230
fn lower_delegation_body(
209231
&mut self,
210-
decl: &'hir hir::FnDecl<'hir>,
211232
delegation: &Delegation,
233+
param_count: usize,
234+
span: Span,
212235
) -> BodyId {
213236
let path = self.lower_qpath(
214237
delegation.id,
@@ -224,8 +247,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
224247
let mut parameters: Vec<hir::Param<'_>> = Vec::new();
225248
let mut args: Vec<hir::Expr<'hir>> = Vec::new();
226249

227-
for (idx, param_ty) in decl.inputs.iter().enumerate() {
228-
let (param, pat_node_id) = this.generate_param(param_ty);
250+
for idx in 0..param_count {
251+
let (param, pat_node_id) = this.generate_param(span);
229252
parameters.push(param);
230253

231254
let arg = if let Some(block) = block
@@ -245,7 +268,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
245268
}
246269
} else {
247270
let pat_hir_id = this.lower_node_id(pat_node_id);
248-
this.generate_arg(param_ty, pat_hir_id)
271+
this.generate_arg(pat_hir_id, span)
249272
};
250273
args.push(arg);
251274
}
@@ -304,14 +327,25 @@ impl<'hir> LoweringContext<'_, 'hir> {
304327
implicit_self: hir::ImplicitSelfKind::None,
305328
});
306329

307-
let sig = self.lower_delegation_sig(span, decl);
330+
let header = self.generate_header_error();
331+
let sig = hir::FnSig { decl, header, span };
332+
308333
let body_id = self.lower_body(|this| {
309334
let expr =
310335
hir::Expr { hir_id: this.next_id(), kind: hir::ExprKind::Err(err), span: span };
311336
(&[], expr)
312337
});
313338
DelegationResults { generics, body_id, sig }
314339
}
340+
341+
fn generate_header_error(&self) -> hir::FnHeader {
342+
hir::FnHeader {
343+
unsafety: hir::Unsafety::Normal,
344+
constness: hir::Constness::NotConst,
345+
asyncness: hir::IsAsync::NotAsync,
346+
abi: abi::Abi::Rust,
347+
}
348+
}
315349
}
316350

317351
struct SelfResolver<'a> {

‎compiler/rustc_ast_lowering/src/item.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1346,7 +1346,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
13461346
(generics, hir::FnSig { header, decl, span: self.lower_span(sig.span) })
13471347
}
13481348

1349-
fn lower_fn_header(&mut self, h: FnHeader) -> hir::FnHeader {
1349+
pub(super) fn lower_fn_header(&mut self, h: FnHeader) -> hir::FnHeader {
13501350
let asyncness = if let Some(CoroutineKind::Async { span, .. }) = h.coroutine_kind {
13511351
hir::IsAsync::Async(span)
13521352
} else {

‎compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs

Lines changed: 0 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -2196,11 +2196,6 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
21962196
try_emit("recursive delegation");
21972197
}
21982198

2199-
let sig = self.tcx().fn_sig(sig_id).instantiate_identity();
2200-
if sig.output().has_opaque_types() {
2201-
try_emit("delegation to a function with opaque type");
2202-
}
2203-
22042199
let sig_generics = self.tcx().generics_of(sig_id);
22052200
let parent = self.tcx().parent(self.item_def_id());
22062201
let parent_generics = self.tcx().generics_of(parent);
@@ -2212,29 +2207,6 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
22122207
try_emit("delegation with early bound generics");
22132208
}
22142209

2215-
if self.tcx().asyncness(sig_id) == ty::Asyncness::Yes {
2216-
try_emit("delegation to async functions");
2217-
}
2218-
2219-
if self.tcx().constness(sig_id) == hir::Constness::Const {
2220-
try_emit("delegation to const functions");
2221-
}
2222-
2223-
if sig.c_variadic() {
2224-
try_emit("delegation to variadic functions");
2225-
// variadic functions are also `unsafe` and `extern "C"`.
2226-
// Do not emit same error multiple times.
2227-
return error_occured;
2228-
}
2229-
2230-
if let hir::Unsafety::Unsafe = sig.unsafety() {
2231-
try_emit("delegation to unsafe functions");
2232-
}
2233-
2234-
if abi::Abi::Rust != sig.abi() {
2235-
try_emit("delegation to non Rust ABI functions");
2236-
}
2237-
22382210
error_occured
22392211
}
22402212

‎compiler/rustc_middle/src/ty/mod.rs

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ use rustc_data_structures::unord::UnordMap;
4545
use rustc_errors::{Diag, ErrorGuaranteed, StashKey};
4646
use rustc_hir as hir;
4747
use rustc_hir::def::{CtorKind, CtorOf, DefKind, DocLinkResMap, LifetimeRes, Res};
48-
use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LocalDefId, LocalDefIdMap, LocalDefIdSet};
48+
use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LocalDefId, LocalDefIdMap};
4949
use rustc_index::IndexVec;
5050
use rustc_macros::HashStable;
5151
use rustc_query_system::ich::StableHashingContext;
@@ -224,8 +224,15 @@ pub struct ResolverAstLowering {
224224
pub lint_buffer: Steal<LintBuffer>,
225225

226226
/// Information about functions signatures for delegation items expansion
227-
pub has_self: LocalDefIdSet,
228-
pub fn_parameter_counts: LocalDefIdMap<usize>,
227+
pub delegation_fn_sigs: LocalDefIdMap<DelegationFnSig>,
228+
}
229+
230+
#[derive(Debug)]
231+
pub struct DelegationFnSig {
232+
pub header: ast::FnHeader,
233+
pub param_count: usize,
234+
pub has_self: bool,
235+
pub c_variadic: bool,
229236
}
230237

231238
#[derive(Clone, Copy, Debug)]

‎compiler/rustc_resolve/src/late.rs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ use rustc_hir::def::{self, CtorKind, DefKind, LifetimeRes, NonMacroAttrKind, Par
2424
use rustc_hir::def_id::{DefId, LocalDefId, CRATE_DEF_ID, LOCAL_CRATE};
2525
use rustc_hir::{MissingLifetimeKind, PrimTy, TraitCandidate};
2626
use rustc_middle::middle::resolve_bound_vars::Set1;
27+
use rustc_middle::ty::DelegationFnSig;
2728
use rustc_middle::{bug, span_bug};
2829
use rustc_session::config::{CrateType, ResolveDocLinks};
2930
use rustc_session::lint;
@@ -4712,12 +4713,13 @@ struct ItemInfoCollector<'a, 'b, 'tcx> {
47124713

47134714
impl ItemInfoCollector<'_, '_, '_> {
47144715
fn collect_fn_info(&mut self, sig: &FnSig, id: NodeId) {
4715-
let def_id = self.r.local_def_id(id);
4716-
self.r.fn_parameter_counts.insert(def_id, sig.decl.inputs.len());
4717-
4718-
if sig.decl.has_self() {
4719-
self.r.has_self.insert(def_id);
4720-
}
4716+
let sig = DelegationFnSig {
4717+
header: sig.header,
4718+
param_count: sig.decl.inputs.len(),
4719+
has_self: sig.decl.has_self(),
4720+
c_variadic: sig.decl.c_variadic(),
4721+
};
4722+
self.r.delegation_fn_sigs.insert(self.r.local_def_id(id), sig);
47214723
}
47224724
}
47234725

‎compiler/rustc_resolve/src/late/diagnostics.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2039,7 +2039,8 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
20392039
ast::AssocItemKind::Fn(..) => AssocSuggestion::AssocFn { called },
20402040
ast::AssocItemKind::Type(..) => AssocSuggestion::AssocType,
20412041
ast::AssocItemKind::Delegation(..)
2042-
if self.r.has_self.contains(&self.r.local_def_id(assoc_item.id)) =>
2042+
if self.r.delegation_fn_sigs[&self.r.local_def_id(assoc_item.id)]
2043+
.has_self =>
20432044
{
20442045
AssocSuggestion::MethodWithSelf { called }
20452046
}
@@ -2062,7 +2063,9 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
20622063
if filter_fn(res) {
20632064
let def_id = res.def_id();
20642065
let has_self = match def_id.as_local() {
2065-
Some(def_id) => self.r.has_self.contains(&def_id),
2066+
Some(def_id) => {
2067+
self.r.delegation_fn_sigs.get(&def_id).map_or(false, |sig| sig.has_self)
2068+
}
20662069
None => self
20672070
.r
20682071
.tcx

‎compiler/rustc_resolve/src/lib.rs

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ use rustc_feature::BUILTIN_ATTRIBUTES;
4343
use rustc_hir::def::Namespace::{self, *};
4444
use rustc_hir::def::NonMacroAttrKind;
4545
use rustc_hir::def::{self, CtorOf, DefKind, DocLinkResMap, LifetimeRes, PartialRes, PerNS};
46-
use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, LocalDefIdMap, LocalDefIdSet};
46+
use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, LocalDefIdMap};
4747
use rustc_hir::def_id::{CRATE_DEF_ID, LOCAL_CRATE};
4848
use rustc_hir::{PrimTy, TraitCandidate};
4949
use rustc_index::IndexVec;
@@ -52,8 +52,8 @@ use rustc_middle::metadata::ModChild;
5252
use rustc_middle::middle::privacy::EffectiveVisibilities;
5353
use rustc_middle::query::Providers;
5454
use rustc_middle::span_bug;
55-
use rustc_middle::ty::{self, MainDefinition, RegisteredTools, TyCtxt, TyCtxtFeed};
56-
use rustc_middle::ty::{Feed, ResolverGlobalCtxt, ResolverOutputs};
55+
use rustc_middle::ty::{self, DelegationFnSig, Feed, MainDefinition, RegisteredTools};
56+
use rustc_middle::ty::{ResolverGlobalCtxt, ResolverOutputs, TyCtxt, TyCtxtFeed};
5757
use rustc_query_system::ich::StableHashingContext;
5858
use rustc_session::lint::builtin::PRIVATE_MACRO_USE;
5959
use rustc_session::lint::LintBuffer;
@@ -979,7 +979,6 @@ pub struct Resolver<'a, 'tcx> {
979979
extern_prelude: FxHashMap<Ident, ExternPreludeEntry<'a>>,
980980

981981
/// N.B., this is used only for better diagnostics, not name resolution itself.
982-
has_self: LocalDefIdSet,
983982
field_def_ids: LocalDefIdMap<&'tcx [DefId]>,
984983

985984
/// Span of the privacy modifier in fields of an item `DefId` accessible with dot syntax.
@@ -1136,8 +1135,7 @@ pub struct Resolver<'a, 'tcx> {
11361135
legacy_const_generic_args: FxHashMap<DefId, Option<Vec<usize>>>,
11371136
/// Amount of lifetime parameters for each item in the crate.
11381137
item_generics_num_lifetimes: FxHashMap<LocalDefId, usize>,
1139-
/// Amount of parameters for each function in the crate.
1140-
fn_parameter_counts: LocalDefIdMap<usize>,
1138+
delegation_fn_sigs: LocalDefIdMap<DelegationFnSig>,
11411139

11421140
main_def: Option<MainDefinition>,
11431141
trait_impls: FxIndexMap<DefId, Vec<LocalDefId>>,
@@ -1386,7 +1384,6 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
13861384
prelude: None,
13871385
extern_prelude,
13881386

1389-
has_self: Default::default(),
13901387
field_def_ids: Default::default(),
13911388
field_visibility_spans: FxHashMap::default(),
13921389

@@ -1495,7 +1492,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
14951492
doc_link_resolutions: Default::default(),
14961493
doc_link_traits_in_scope: Default::default(),
14971494
all_macro_rules: Default::default(),
1498-
fn_parameter_counts: Default::default(),
1495+
delegation_fn_sigs: Default::default(),
14991496
};
15001497

15011498
let root_parent_scope = ParentScope::module(graph_root, &resolver);
@@ -1609,8 +1606,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
16091606
trait_map: self.trait_map,
16101607
lifetime_elision_allowed: self.lifetime_elision_allowed,
16111608
lint_buffer: Steal::new(self.lint_buffer),
1612-
has_self: self.has_self,
1613-
fn_parameter_counts: self.fn_parameter_counts,
1609+
delegation_fn_sigs: self.delegation_fn_sigs,
16141610
};
16151611
ResolverOutputs { global_ctxt, ast_lowering }
16161612
}

‎tests/ui/delegation/fn-header.rs

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
//@ check-pass
2+
//@ edition:2018
3+
4+
#![feature(c_variadic)]
5+
#![feature(fn_delegation)]
6+
#![allow(incomplete_features)]
7+
8+
mod to_reuse {
9+
pub unsafe fn unsafe_fn() {}
10+
pub extern "C" fn extern_fn() {}
11+
pub unsafe extern "C" fn variadic_fn(n: usize, mut args: ...) {}
12+
pub const fn const_fn() {}
13+
pub async fn async_fn() {}
14+
}
15+
16+
reuse to_reuse::unsafe_fn;
17+
reuse to_reuse::extern_fn;
18+
reuse to_reuse::variadic_fn;
19+
reuse to_reuse::const_fn;
20+
reuse to_reuse::async_fn;
21+
22+
const fn const_check() {
23+
const_fn();
24+
}
25+
26+
async fn async_check() {
27+
async_fn();
28+
}
29+
30+
fn main() {
31+
unsafe {
32+
unsafe_fn();
33+
}
34+
extern_fn();
35+
let _: extern "C" fn() = extern_fn;
36+
unsafe {
37+
variadic_fn(0);
38+
variadic_fn(0, 1);
39+
}
40+
let _: unsafe extern "C" fn(usize, ...) = variadic_fn;
41+
}

‎tests/ui/delegation/impl-trait.rs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
//@ check-pass
2+
3+
#![feature(fn_delegation)]
4+
#![allow(incomplete_features)]
5+
6+
mod to_reuse {
7+
pub fn foo() -> impl Clone { 0 }
8+
}
9+
10+
reuse to_reuse::foo;
11+
12+
trait Trait {
13+
fn bar() -> impl Clone { 1 }
14+
}
15+
16+
struct S;
17+
impl Trait for S {}
18+
19+
impl S {
20+
reuse to_reuse::foo;
21+
reuse <S as Trait>::bar;
22+
}
23+
24+
fn main() {
25+
foo().clone();
26+
<S>::bar().clone();
27+
}

‎tests/ui/delegation/not-supported.rs

Lines changed: 12 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#![feature(c_variadic)]
22
#![feature(fn_delegation)]
3-
//~^ WARN the feature `fn_delegation` is incomplete
3+
#![allow(incomplete_features)]
44

55
mod generics {
66
trait GenericTrait<T> {
@@ -14,9 +14,9 @@ mod generics {
1414
fn foo3<'a: 'a>(_: &'a u32) {}
1515

1616
reuse GenericTrait::bar;
17-
//~^ delegation with early bound generics is not supported yet
17+
//~^ ERROR delegation with early bound generics is not supported yet
1818
reuse GenericTrait::bar1;
19-
//~^ delegation with early bound generics is not supported yet
19+
//~^ ERROR delegation with early bound generics is not supported yet
2020
}
2121

2222
struct F;
@@ -73,26 +73,18 @@ mod opaque {
7373
}
7474
reuse to_reuse::opaque_arg;
7575
//~^ ERROR delegation with early bound generics is not supported yet
76-
reuse to_reuse::opaque_ret;
77-
//~^ ERROR delegation to a function with opaque type is not supported yet
78-
}
7976

80-
mod fn_header {
81-
mod to_reuse {
82-
pub unsafe fn unsafe_fn() {}
83-
pub extern "C" fn extern_fn() {}
84-
pub unsafe extern "C" fn variadic_fn(n: usize, mut args: ...) {}
85-
pub const fn const_fn() {}
77+
trait ToReuse {
78+
fn opaque_ret() -> impl Trait { unimplemented!() }
8679
}
8780

88-
reuse to_reuse::unsafe_fn;
89-
//~^ ERROR delegation to unsafe functions is not supported yet
90-
reuse to_reuse::extern_fn;
91-
//~^ ERROR delegation to non Rust ABI functions is not supported yet
92-
reuse to_reuse::variadic_fn;
93-
//~^ ERROR delegation to variadic functions is not supported yet
94-
reuse to_reuse::const_fn;
95-
//~^ ERROR delegation to const functions is not supported yet
81+
// FIXME: Inherited `impl Trait`s create query cycles when used inside trait impls.
82+
impl ToReuse for u8 {
83+
reuse to_reuse::opaque_ret; //~ ERROR cycle detected when computing type
84+
}
85+
impl ToReuse for u16 {
86+
reuse ToReuse::opaque_ret; //~ ERROR cycle detected when computing type
87+
}
9688
}
9789

9890
mod recursive {

‎tests/ui/delegation/not-supported.stderr

Lines changed: 34 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,3 @@
1-
warning: the feature `fn_delegation` is incomplete and may not be safe to use and/or cause compiler crashes
2-
--> $DIR/not-supported.rs:2:12
3-
|
4-
LL | #![feature(fn_delegation)]
5-
| ^^^^^^^^^^^^^
6-
|
7-
= note: see issue #118212 <https://github.com/rust-lang/rust/issues/118212> for more information
8-
= note: `#[warn(incomplete_features)]` on by default
9-
101
error: delegation with early bound generics is not supported yet
112
--> $DIR/not-supported.rs:16:29
123
|
@@ -124,61 +115,54 @@ LL | pub fn opaque_arg(_: impl Trait) -> i32 { 0 }
124115
LL | reuse to_reuse::opaque_arg;
125116
| ^^^^^^^^^^
126117

127-
error: delegation to a function with opaque type is not supported yet
128-
--> $DIR/not-supported.rs:76:21
118+
error[E0391]: cycle detected when computing type of `opaque::<impl at $DIR/not-supported.rs:82:5: 82:24>::{synthetic#0}`
119+
--> $DIR/not-supported.rs:83:25
129120
|
130-
LL | pub fn opaque_ret() -> impl Trait { unimplemented!() }
131-
| --------------------------------- callee defined here
132-
...
133-
LL | reuse to_reuse::opaque_ret;
134-
| ^^^^^^^^^^
135-
136-
error: delegation to unsafe functions is not supported yet
137-
--> $DIR/not-supported.rs:88:21
121+
LL | reuse to_reuse::opaque_ret;
122+
| ^^^^^^^^^^
138123
|
139-
LL | pub unsafe fn unsafe_fn() {}
140-
| ------------------------- callee defined here
141-
...
142-
LL | reuse to_reuse::unsafe_fn;
143-
| ^^^^^^^^^
144-
145-
error: delegation to non Rust ABI functions is not supported yet
146-
--> $DIR/not-supported.rs:90:21
124+
note: ...which requires comparing an impl and trait method signature, inferring any hidden `impl Trait` types in the process...
125+
--> $DIR/not-supported.rs:83:25
147126
|
148-
LL | pub extern "C" fn extern_fn() {}
149-
| ----------------------------- callee defined here
150-
...
151-
LL | reuse to_reuse::extern_fn;
152-
| ^^^^^^^^^
153-
154-
error: delegation to variadic functions is not supported yet
155-
--> $DIR/not-supported.rs:92:21
127+
LL | reuse to_reuse::opaque_ret;
128+
| ^^^^^^^^^^
129+
= note: ...which again requires computing type of `opaque::<impl at $DIR/not-supported.rs:82:5: 82:24>::{synthetic#0}`, completing the cycle
130+
note: cycle used when checking that `opaque::<impl at $DIR/not-supported.rs:82:5: 82:24>` is well-formed
131+
--> $DIR/not-supported.rs:82:5
156132
|
157-
LL | pub unsafe extern "C" fn variadic_fn(n: usize, mut args: ...) {}
158-
| ------------------------------------------------------------- callee defined here
159-
...
160-
LL | reuse to_reuse::variadic_fn;
161-
| ^^^^^^^^^^^
133+
LL | impl ToReuse for u8 {
134+
| ^^^^^^^^^^^^^^^^^^^
135+
= note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
162136

163-
error: delegation to const functions is not supported yet
164-
--> $DIR/not-supported.rs:94:21
137+
error[E0391]: cycle detected when computing type of `opaque::<impl at $DIR/not-supported.rs:85:5: 85:25>::{synthetic#0}`
138+
--> $DIR/not-supported.rs:86:24
165139
|
166-
LL | pub const fn const_fn() {}
167-
| ----------------------- callee defined here
168-
...
169-
LL | reuse to_reuse::const_fn;
170-
| ^^^^^^^^
140+
LL | reuse ToReuse::opaque_ret;
141+
| ^^^^^^^^^^
142+
|
143+
note: ...which requires comparing an impl and trait method signature, inferring any hidden `impl Trait` types in the process...
144+
--> $DIR/not-supported.rs:86:24
145+
|
146+
LL | reuse ToReuse::opaque_ret;
147+
| ^^^^^^^^^^
148+
= note: ...which again requires computing type of `opaque::<impl at $DIR/not-supported.rs:85:5: 85:25>::{synthetic#0}`, completing the cycle
149+
note: cycle used when checking that `opaque::<impl at $DIR/not-supported.rs:85:5: 85:25>` is well-formed
150+
--> $DIR/not-supported.rs:85:5
151+
|
152+
LL | impl ToReuse for u16 {
153+
| ^^^^^^^^^^^^^^^^^^^^
154+
= note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
171155

172156
error: recursive delegation is not supported yet
173-
--> $DIR/not-supported.rs:107:22
157+
--> $DIR/not-supported.rs:99:22
174158
|
175159
LL | pub reuse to_reuse2::foo;
176160
| --- callee defined here
177161
...
178162
LL | reuse to_reuse1::foo;
179163
| ^^^
180164

181-
error: aborting due to 19 previous errors; 1 warning emitted
165+
error: aborting due to 16 previous errors
182166

183-
Some errors have detailed explanations: E0049, E0195.
167+
Some errors have detailed explanations: E0049, E0195, E0391.
184168
For more information about an error, try `rustc --explain E0049`.

0 commit comments

Comments
 (0)
Please sign in to comment.