Skip to content

Commit f3033f3

Browse files
Conditionally allow lowering RTN (..) in paths
1 parent 81d113a commit f3033f3

File tree

13 files changed

+141
-54
lines changed

13 files changed

+141
-54
lines changed

compiler/rustc_ast_lowering/src/asm.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ use super::errors::{
2020
};
2121
use super::LoweringContext;
2222
use crate::{
23-
fluent_generated as fluent, ImplTraitContext, ImplTraitPosition, ParamMode,
24-
ResolverAstLoweringExt,
23+
fluent_generated as fluent, AllowReturnTypeNotation, ImplTraitContext, ImplTraitPosition,
24+
ParamMode, ResolverAstLoweringExt,
2525
};
2626

2727
impl<'a, 'hir> LoweringContext<'a, 'hir> {
@@ -201,6 +201,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
201201
&sym.qself,
202202
&sym.path,
203203
ParamMode::Optional,
204+
AllowReturnTypeNotation::No,
204205
ImplTraitContext::Disallowed(ImplTraitPosition::Path),
205206
None,
206207
);

compiler/rustc_ast_lowering/src/delegation.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ use rustc_target::spec::abi;
5252
use {rustc_ast as ast, rustc_hir as hir};
5353

5454
use super::{GenericArgsMode, ImplTraitContext, LoweringContext, ParamMode};
55-
use crate::{ImplTraitPosition, ResolverAstLoweringExt};
55+
use crate::{AllowReturnTypeNotation, ImplTraitPosition, ResolverAstLoweringExt};
5656

5757
pub(crate) struct DelegationResults<'hir> {
5858
pub body_id: hir::BodyId,
@@ -340,6 +340,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
340340
&delegation.qself,
341341
&delegation.path,
342342
ParamMode::Optional,
343+
AllowReturnTypeNotation::No,
343344
ImplTraitContext::Disallowed(ImplTraitPosition::Path),
344345
None,
345346
);

compiler/rustc_ast_lowering/src/expr.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ use super::{
2323
GenericArgsMode, ImplTraitContext, LoweringContext, ParamMode, ResolverAstLoweringExt,
2424
};
2525
use crate::errors::YieldInClosure;
26-
use crate::{fluent_generated, FnDeclKind, ImplTraitPosition};
26+
use crate::{fluent_generated, AllowReturnTypeNotation, FnDeclKind, ImplTraitPosition};
2727

2828
impl<'hir> LoweringContext<'_, 'hir> {
2929
fn lower_exprs(&mut self, exprs: &[AstP<Expr>]) -> &'hir [hir::Expr<'hir>] {
@@ -281,6 +281,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
281281
qself,
282282
path,
283283
ParamMode::Optional,
284+
AllowReturnTypeNotation::No,
284285
ImplTraitContext::Disallowed(ImplTraitPosition::Path),
285286
None,
286287
);
@@ -328,6 +329,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
328329
&se.qself,
329330
&se.path,
330331
ParamMode::Optional,
332+
AllowReturnTypeNotation::No,
331333
ImplTraitContext::Disallowed(ImplTraitPosition::Path),
332334
None,
333335
)),
@@ -1291,6 +1293,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
12911293
qself,
12921294
path,
12931295
ParamMode::Optional,
1296+
AllowReturnTypeNotation::No,
12941297
ImplTraitContext::Disallowed(ImplTraitPosition::Path),
12951298
None,
12961299
);
@@ -1311,6 +1314,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
13111314
qself,
13121315
path,
13131316
ParamMode::Optional,
1317+
AllowReturnTypeNotation::No,
13141318
ImplTraitContext::Disallowed(ImplTraitPosition::Path),
13151319
None,
13161320
);
@@ -1336,6 +1340,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
13361340
&se.qself,
13371341
&se.path,
13381342
ParamMode::Optional,
1343+
AllowReturnTypeNotation::No,
13391344
ImplTraitContext::Disallowed(ImplTraitPosition::Path),
13401345
None,
13411346
);

compiler/rustc_ast_lowering/src/lib.rs

+21-1
Original file line numberDiff line numberDiff line change
@@ -485,8 +485,16 @@ enum ParamMode {
485485
Optional,
486486
}
487487

488+
#[derive(Copy, Clone, Debug)]
489+
enum AllowReturnTypeNotation {
490+
Yes,
491+
No,
492+
}
493+
494+
#[derive(Copy, Clone, Debug)]
488495
enum GenericArgsMode {
489496
ParenSugar,
497+
ReturnTypeNotation,
490498
Err,
491499
}
492500

@@ -1226,7 +1234,16 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
12261234
}
12271235

12281236
let id = self.lower_node_id(t.id);
1229-
let qpath = self.lower_qpath(t.id, qself, path, param_mode, itctx, None);
1237+
let qpath = self.lower_qpath(
1238+
t.id,
1239+
qself,
1240+
path,
1241+
param_mode,
1242+
// We deny these after the fact in HIR->middle type lowering.
1243+
AllowReturnTypeNotation::Yes,
1244+
itctx,
1245+
None,
1246+
);
12301247
self.ty_path(id, t.span, qpath)
12311248
}
12321249

@@ -2224,6 +2241,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
22242241
&None,
22252242
&p.path,
22262243
ParamMode::Explicit,
2244+
AllowReturnTypeNotation::No,
22272245
itctx,
22282246
Some(modifiers),
22292247
) {
@@ -2362,6 +2380,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
23622380
&None,
23632381
path,
23642382
ParamMode::Optional,
2383+
AllowReturnTypeNotation::No,
23652384
ImplTraitContext::Disallowed(ImplTraitPosition::Path),
23662385
None,
23672386
);
@@ -2441,6 +2460,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
24412460
qself,
24422461
path,
24432462
ParamMode::Optional,
2463+
AllowReturnTypeNotation::No,
24442464
ImplTraitContext::Disallowed(ImplTraitPosition::Path),
24452465
None,
24462466
);

compiler/rustc_ast_lowering/src/pat.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use super::errors::{
1111
ArbitraryExpressionInPattern, ExtraDoubleDot, MisplacedDoubleDot, SubTupleBinding,
1212
};
1313
use super::{ImplTraitContext, LoweringContext, ParamMode, ResolverAstLoweringExt};
14-
use crate::ImplTraitPosition;
14+
use crate::{AllowReturnTypeNotation, ImplTraitPosition};
1515

1616
impl<'a, 'hir> LoweringContext<'a, 'hir> {
1717
pub(crate) fn lower_pat(&mut self, pattern: &Pat) -> &'hir hir::Pat<'hir> {
@@ -38,6 +38,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
3838
qself,
3939
path,
4040
ParamMode::Optional,
41+
AllowReturnTypeNotation::No,
4142
ImplTraitContext::Disallowed(ImplTraitPosition::Path),
4243
None,
4344
);
@@ -55,6 +56,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
5556
qself,
5657
path,
5758
ParamMode::Optional,
59+
AllowReturnTypeNotation::No,
5860
ImplTraitContext::Disallowed(ImplTraitPosition::Path),
5961
None,
6062
);
@@ -66,6 +68,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
6668
qself,
6769
path,
6870
ParamMode::Optional,
71+
AllowReturnTypeNotation::No,
6972
ImplTraitContext::Disallowed(ImplTraitPosition::Path),
7073
None,
7174
);

compiler/rustc_ast_lowering/src/path.rs

+62-4
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use rustc_hir::def::{DefKind, PartialRes, Res};
55
use rustc_hir::def_id::DefId;
66
use rustc_hir::GenericArg;
77
use rustc_middle::span_bug;
8+
use rustc_session::parse::add_feature_diagnostics;
89
use rustc_span::symbol::{kw, sym, Ident};
910
use rustc_span::{BytePos, DesugaringKind, Span, Symbol, DUMMY_SP};
1011
use smallvec::{smallvec, SmallVec};
@@ -15,8 +16,8 @@ use super::errors::{
1516
GenericTypeWithParentheses, UseAngleBrackets,
1617
};
1718
use super::{
18-
GenericArgsCtor, GenericArgsMode, ImplTraitContext, LifetimeRes, LoweringContext, ParamMode,
19-
ResolverAstLoweringExt,
19+
AllowReturnTypeNotation, GenericArgsCtor, GenericArgsMode, ImplTraitContext, LifetimeRes,
20+
LoweringContext, ParamMode, ResolverAstLoweringExt,
2021
};
2122
use crate::ImplTraitPosition;
2223

@@ -28,6 +29,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
2829
qself: &Option<ptr::P<QSelf>>,
2930
p: &Path,
3031
param_mode: ParamMode,
32+
allow_return_type_notation: AllowReturnTypeNotation,
3133
itctx: ImplTraitContext,
3234
// modifiers of the impl/bound if this is a trait path
3335
modifiers: Option<ast::TraitBoundModifiers>,
@@ -103,6 +105,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
103105
{
104106
GenericArgsMode::ParenSugar
105107
}
108+
Res::Def(DefKind::AssocFn, _) if i + 1 == proj_start => {
109+
match allow_return_type_notation {
110+
AllowReturnTypeNotation::Yes => GenericArgsMode::ReturnTypeNotation,
111+
AllowReturnTypeNotation::No => GenericArgsMode::Err,
112+
}
113+
}
106114
// Avoid duplicated errors.
107115
Res::Err => GenericArgsMode::ParenSugar,
108116
// An error
@@ -164,11 +172,20 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
164172
// 3. `<<std::vec::Vec<T>>::IntoIter>::Item`
165173
// * final path is `<<<std::vec::Vec<T>>::IntoIter>::Item>::clone`
166174
for (i, segment) in p.segments.iter().enumerate().skip(proj_start) {
175+
// If this is a type-dependent `T::method(..)`.
176+
let generic_args_mode = if i + 1 == p.segments.len()
177+
&& matches!(allow_return_type_notation, AllowReturnTypeNotation::Yes)
178+
{
179+
GenericArgsMode::ReturnTypeNotation
180+
} else {
181+
GenericArgsMode::Err
182+
};
183+
167184
let hir_segment = self.arena.alloc(self.lower_path_segment(
168185
p.span,
169186
segment,
170187
param_mode,
171-
GenericArgsMode::Err,
188+
generic_args_mode,
172189
itctx,
173190
None,
174191
));
@@ -238,6 +255,40 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
238255
self.lower_angle_bracketed_parameter_data(data, param_mode, itctx)
239256
}
240257
GenericArgs::Parenthesized(data) => match generic_args_mode {
258+
GenericArgsMode::ReturnTypeNotation => {
259+
let mut err = if !data.inputs.is_empty() {
260+
self.dcx().create_err(BadReturnTypeNotation::Inputs {
261+
span: data.inputs_span,
262+
})
263+
} else if let FnRetTy::Ty(ty) = &data.output {
264+
self.dcx().create_err(BadReturnTypeNotation::Output {
265+
span: data.inputs_span.shrink_to_hi().to(ty.span),
266+
})
267+
} else {
268+
self.dcx().create_err(BadReturnTypeNotation::NeedsDots {
269+
span: data.inputs_span,
270+
})
271+
};
272+
if !self.tcx.features().return_type_notation
273+
&& self.tcx.sess.is_nightly_build()
274+
{
275+
add_feature_diagnostics(
276+
&mut err,
277+
&self.tcx.sess,
278+
sym::return_type_notation,
279+
);
280+
}
281+
err.emit();
282+
(
283+
GenericArgsCtor {
284+
args: Default::default(),
285+
constraints: &[],
286+
parenthesized: hir::GenericArgsParentheses::ReturnTypeNotation,
287+
span: path_span,
288+
},
289+
false,
290+
)
291+
}
241292
GenericArgsMode::ParenSugar => self.lower_parenthesized_parameter_data(
242293
data,
243294
itctx,
@@ -279,7 +330,14 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
279330
}
280331
},
281332
GenericArgs::ParenthesizedElided(span) => {
282-
self.dcx().emit_err(BadReturnTypeNotation::Position { span: *span });
333+
match generic_args_mode {
334+
GenericArgsMode::ReturnTypeNotation => {
335+
// Ok
336+
}
337+
GenericArgsMode::ParenSugar | GenericArgsMode::Err => {
338+
self.dcx().emit_err(BadReturnTypeNotation::Position { span: *span });
339+
}
340+
}
283341
(
284342
GenericArgsCtor {
285343
args: Default::default(),

compiler/rustc_hir_analysis/messages.ftl

+2
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ hir_analysis_auto_deref_reached_recursion_limit = reached the recursion limit wh
4848
4949
hir_analysis_bad_precise_capture = expected {$kind} parameter in `use<...>` precise captures list, found {$found}
5050
51+
hir_analysis_bad_return_type_notation_position = return type notation not allowed in this position yet
52+
5153
hir_analysis_cannot_capture_late_bound_const =
5254
cannot capture late-bound const parameter in {$what}
5355
.label = parameter defined here

compiler/rustc_hir_analysis/src/errors.rs

+7
Original file line numberDiff line numberDiff line change
@@ -1744,3 +1744,10 @@ pub struct CmseCallGeneric {
17441744
#[primary_span]
17451745
pub span: Span,
17461746
}
1747+
1748+
#[derive(Diagnostic)]
1749+
#[diag(hir_analysis_bad_return_type_notation_position)]
1750+
pub struct BadReturnTypeNotation {
1751+
#[primary_span]
1752+
pub span: Span,
1753+
}

compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs

+14-1
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ use rustc_trait_selection::traits::wf::object_region_bounds;
5252
use rustc_trait_selection::traits::{self, ObligationCtxt};
5353

5454
use crate::bounds::Bounds;
55-
use crate::errors::{AmbiguousLifetimeBound, WildPatTy};
55+
use crate::errors::{AmbiguousLifetimeBound, BadReturnTypeNotation, WildPatTy};
5656
use crate::hir_ty_lowering::errors::{prohibit_assoc_item_constraint, GenericsArgsErrExtend};
5757
use crate::hir_ty_lowering::generics::{check_generic_arg_count, lower_generic_args};
5858
use crate::middle::resolve_bound_vars as rbv;
@@ -1911,6 +1911,19 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
19111911
ty::BoundConstness::NotConst,
19121912
)
19131913
}
1914+
// Deny any qpath types that were successfully lowered in AST lowering.
1915+
Res::Def(DefKind::AssocFn, _)
1916+
if let [.., _trait_segment, item_segment] = &path.segments[..]
1917+
&& item_segment.args.is_some_and(|args| {
1918+
matches!(
1919+
args.parenthesized,
1920+
hir::GenericArgsParentheses::ReturnTypeNotation
1921+
)
1922+
}) =>
1923+
{
1924+
let guar = self.dcx().emit_err(BadReturnTypeNotation { span: path.span });
1925+
Ty::new_error(tcx, guar)
1926+
}
19141927
Res::PrimTy(prim_ty) => {
19151928
assert_eq!(opt_self_ty, None);
19161929
let _ = self.prohibit_generic_args(

tests/ui/associated-type-bounds/return-type-notation/bare-path.rs

+2-5
Original file line numberDiff line numberDiff line change
@@ -10,17 +10,14 @@ trait Tr {
1010
fn foo<T: Tr>()
1111
where
1212
T::method(..): Send,
13-
//~^ ERROR return type notation not allowed in this position yet
14-
//~| ERROR expected type, found function
13+
//~^ ERROR expected type, found function
1514
<T as Tr>::method(..): Send,
1615
//~^ ERROR return type notation not allowed in this position yet
17-
//~| ERROR expected associated type, found associated function `Tr::method`
1816
{
1917
let _ = T::CONST::(..);
2018
//~^ ERROR return type notation not allowed in this position yet
2119
let _: T::method(..);
22-
//~^ ERROR return type notation not allowed in this position yet
23-
//~| ERROR expected type, found function
20+
//~^ ERROR expected type, found function
2421
}
2522

2623
fn main() {}

0 commit comments

Comments
 (0)