Skip to content

Commit 52c6b10

Browse files
Use a path instead of an ident (and stop manually resolving)
1 parent ce89610 commit 52c6b10

File tree

12 files changed

+81
-84
lines changed

12 files changed

+81
-84
lines changed

compiler/rustc_ast/src/ast.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -2188,12 +2188,12 @@ pub enum TraitObjectSyntax {
21882188
None,
21892189
}
21902190

2191-
#[derive(Clone, PartialEq, Encodable, Decodable, Debug)]
2191+
#[derive(Clone, Encodable, Decodable, Debug)]
21922192
pub enum PreciseCapturingArg {
21932193
/// Lifetime parameter
21942194
Lifetime(Lifetime),
21952195
/// Type or const parameter
2196-
Arg(Ident, NodeId),
2196+
Arg(Path, NodeId),
21972197
}
21982198

21992199
/// Inline assembly operand explicit register or register class.

compiler/rustc_ast/src/mut_visit.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -928,8 +928,8 @@ pub fn noop_visit_precise_capturing_arg<T: MutVisitor>(arg: &mut PreciseCapturin
928928
PreciseCapturingArg::Lifetime(lt) => {
929929
vis.visit_lifetime(lt);
930930
}
931-
PreciseCapturingArg::Arg(ident, id) => {
932-
vis.visit_ident(ident);
931+
PreciseCapturingArg::Arg(path, id) => {
932+
vis.visit_path(path);
933933
vis.visit_id(id);
934934
}
935935
}

compiler/rustc_ast/src/visit.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -653,8 +653,8 @@ pub fn walk_precise_capturing_arg<'a, V: Visitor<'a>>(
653653
PreciseCapturingArg::Lifetime(lt) => {
654654
visitor.visit_lifetime(lt, LifetimeCtxt::GenericArg);
655655
}
656-
PreciseCapturingArg::Arg(ident, _) => {
657-
visitor.visit_ident(*ident);
656+
PreciseCapturingArg::Arg(path, id) => {
657+
visitor.visit_path(path, *id);
658658
}
659659
}
660660
}

compiler/rustc_ast_lowering/src/lib.rs

+7-4
Original file line numberDiff line numberDiff line change
@@ -1790,13 +1790,16 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
17901790
PreciseCapturingArg::Lifetime(lt) => {
17911791
hir::PreciseCapturingArg::Lifetime(self.lower_lifetime(lt))
17921792
}
1793-
PreciseCapturingArg::Arg(ident, node_id) => {
1794-
let res = self.resolver.get_partial_res(*node_id).map_or(Res::Err, |partial_res| {
1793+
PreciseCapturingArg::Arg(path, id) => {
1794+
let [segment] = path.segments.as_slice() else {
1795+
panic!();
1796+
};
1797+
let res = self.resolver.get_partial_res(*id).map_or(Res::Err, |partial_res| {
17951798
partial_res.full_res().expect("no partial res expected for precise capture arg")
17961799
});
17971800
hir::PreciseCapturingArg::Param(hir::PreciseCapturingNonLifetimeArg {
1798-
hir_id: self.lower_node_id(*node_id),
1799-
ident: self.lower_ident(*ident),
1801+
hir_id: self.lower_node_id(*id),
1802+
ident: self.lower_ident(segment.ident),
18001803
res: self.lower_res(res),
18011804
})
18021805
}

compiler/rustc_ast_pretty/src/pprust/state.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1156,7 +1156,7 @@ impl<'a> State<'a> {
11561156
self.word("use");
11571157
self.word("<");
11581158
self.commasep(Inconsistent, precise_capturing_args, |s, arg| match arg {
1159-
ast::PreciseCapturingArg::Arg(a, _) => s.print_ident(*a),
1159+
ast::PreciseCapturingArg::Arg(p, _) => s.print_path(p, false, 0),
11601160
ast::PreciseCapturingArg::Lifetime(lt) => s.print_lifetime(*lt),
11611161
});
11621162
self.word(">")

compiler/rustc_hir_analysis/messages.ftl

+3
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@ hir_analysis_auto_deref_reached_recursion_limit = reached the recursion limit wh
3939
4040
hir_analysis_bad_precise_capture = expected {$kind} parameter in `use<...>` precise captures list, found {$found}
4141
42+
hir_analysis_precise_capture_self_alias = `Self` can't be captured in `use<...>` precise captures list, since it is an alias
43+
.label = `Self` is not a generic argument, but an alias to the type of the {$what}
44+
4245
hir_analysis_cannot_capture_late_bound_const =
4346
cannot capture late-bound const parameter in {$what}
4447
.label = parameter defined here

compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs

+13-3
Original file line numberDiff line numberDiff line change
@@ -583,9 +583,19 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
583583
self.resolve_type_ref(def_id.expect_local(), param.hir_id);
584584
}
585585
Res::Err => {}
586-
_ => {
587-
// This is handled in resolve
588-
self.tcx.dcx().delayed_bug(format!("parameter should have been resolved"));
586+
Res::SelfTyAlias { alias_to, .. } => {
587+
self.tcx.dcx().emit_err(errors::PreciseCaptureSelfAlias {
588+
span: param.ident.span,
589+
self_span: self.tcx.def_span(alias_to),
590+
what: self.tcx.def_descr(alias_to),
591+
});
592+
}
593+
res => {
594+
self.tcx.dcx().emit_err(errors::BadPreciseCapture {
595+
span: param.ident.span,
596+
kind: "type or const",
597+
found: res.descr().to_string(),
598+
});
589599
}
590600
},
591601
}

compiler/rustc_hir_analysis/src/errors/precise_captures.rs

+10
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,16 @@ pub struct BadPreciseCapture {
3232
pub found: String,
3333
}
3434

35+
#[derive(Diagnostic)]
36+
#[diag(hir_analysis_precise_capture_self_alias)]
37+
pub struct PreciseCaptureSelfAlias {
38+
#[primary_span]
39+
pub span: Span,
40+
#[label]
41+
pub self_span: Span,
42+
pub what: &'static str,
43+
}
44+
3545
#[derive(Diagnostic)]
3646
#[diag(hir_analysis_duplicate_precise_capture)]
3747
pub struct DuplicatePreciseCapture {

compiler/rustc_parse/src/parser/ty.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -697,11 +697,14 @@ impl<'a> Parser<'a> {
697697
if self_.check_keyword(kw::SelfUpper) {
698698
self_.bump();
699699
Ok(PreciseCapturingArg::Arg(
700-
self_.prev_token.ident().unwrap().0,
700+
ast::Path::from_ident(self_.prev_token.ident().unwrap().0),
701701
DUMMY_NODE_ID,
702702
))
703703
} else if self_.check_ident() {
704-
Ok(PreciseCapturingArg::Arg(self_.parse_ident().unwrap(), DUMMY_NODE_ID))
704+
Ok(PreciseCapturingArg::Arg(
705+
ast::Path::from_ident(self_.parse_ident()?),
706+
DUMMY_NODE_ID,
707+
))
705708
} else if self_.check_lifetime() {
706709
Ok(PreciseCapturingArg::Lifetime(self_.expect_lifetime()))
707710
} else {

compiler/rustc_resolve/src/late.rs

+12-54
Original file line numberDiff line numberDiff line change
@@ -1056,64 +1056,22 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast,
10561056
match arg {
10571057
// Lower the lifetime regularly; we'll resolve the lifetime and check
10581058
// it's a parameter later on in HIR lowering.
1059-
PreciseCapturingArg::Lifetime(_) => visit::walk_precise_capturing_arg(self, arg),
1059+
PreciseCapturingArg::Lifetime(_) => {}
10601060

1061-
PreciseCapturingArg::Arg(ident, node_id) => {
1062-
let ident = ident.normalize_to_macros_2_0();
1063-
'found: {
1064-
for (rib_t, rib_v) in
1065-
std::iter::zip(&self.ribs.type_ns, &self.ribs.value_ns).rev()
1066-
{
1067-
if let Some(res) = rib_t.bindings.get(&ident).or(rib_v.bindings.get(&ident))
1068-
{
1069-
self.r.record_partial_res(*node_id, PartialRes::new(*res));
1070-
1071-
// Validate that this is a parameter
1072-
match res {
1073-
Res::Def(DefKind::TyParam | DefKind::ConstParam, _)
1074-
| Res::SelfTyParam { .. } => {}
1075-
Res::SelfTyAlias { .. } => {
1076-
self.report_error(
1077-
ident.span,
1078-
ResolutionError::FailedToResolve {
1079-
segment: Some(ident.name),
1080-
label: "`Self` cannot be captured because it is not a type parameter".to_string(),
1081-
suggestion: None,
1082-
module: None,
1083-
},
1084-
);
1085-
}
1086-
_ => {
1087-
self.report_error(
1088-
ident.span,
1089-
ResolutionError::FailedToResolve {
1090-
segment: Some(ident.name),
1091-
label: format!(
1092-
"expected type or const parameter, found {}",
1093-
res.descr()
1094-
),
1095-
suggestion: None,
1096-
module: None,
1097-
},
1098-
);
1099-
}
1100-
}
1101-
1102-
break 'found;
1103-
}
1104-
}
1105-
self.report_error(
1106-
ident.span,
1107-
ResolutionError::FailedToResolve {
1108-
segment: Some(ident.name),
1109-
label: "could not find type or const parameter".to_string(),
1110-
suggestion: None,
1111-
module: None,
1112-
},
1113-
);
1061+
PreciseCapturingArg::Arg(path, id) => {
1062+
let mut check_ns = |ns| {
1063+
self.maybe_resolve_ident_in_lexical_scope(path.segments[0].ident, ns).is_some()
1064+
};
1065+
// Like `Ty::Param`, we try resolving this as both a const and a type.
1066+
if !check_ns(TypeNS) && check_ns(ValueNS) {
1067+
self.smart_resolve_path(*id, &None, path, PathSource::Expr(None));
1068+
} else {
1069+
self.smart_resolve_path(*id, &None, path, PathSource::Type);
11141070
}
11151071
}
11161072
}
1073+
1074+
visit::walk_precise_capturing_arg(self, arg)
11171075
}
11181076

11191077
fn visit_generics(&mut self, generics: &'ast Generics) {

tests/ui/impl-trait/precise-capturing/bad-params.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,15 @@
22
//~^ WARN the feature `precise_capturing` is incomplete
33

44
fn missing() -> impl use<T> Sized {}
5-
//~^ ERROR could not find type or const parameter
5+
//~^ ERROR cannot find type `T` in this scope
66

77
fn missing_self() -> impl use<Self> Sized {}
8-
//~^ ERROR could not find type or const parameter
8+
//~^ ERROR cannot find type `Self` in this scope
99

1010
struct MyType;
1111
impl MyType {
1212
fn self_is_not_param() -> impl use<Self> Sized {}
13-
//~^ ERROR `Self` cannot be captured because it is not a type parameter
13+
//~^ ERROR `Self` can't be captured in `use<...>` precise captures list, since it is an alias
1414
}
1515

1616
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,21 @@
1-
error[E0433]: failed to resolve: could not find type or const parameter
1+
error[E0412]: cannot find type `T` in this scope
22
--> $DIR/bad-params.rs:4:26
33
|
44
LL | fn missing() -> impl use<T> Sized {}
5-
| ^ could not find type or const parameter
5+
| ^ not found in this scope
6+
|
7+
help: you might be missing a type parameter
8+
|
9+
LL | fn missing<T>() -> impl use<T> Sized {}
10+
| +++
611

7-
error[E0433]: failed to resolve: could not find type or const parameter
12+
error[E0411]: cannot find type `Self` in this scope
813
--> $DIR/bad-params.rs:7:31
914
|
1015
LL | fn missing_self() -> impl use<Self> Sized {}
11-
| ^^^^ could not find type or const parameter
12-
13-
error[E0433]: failed to resolve: `Self` cannot be captured because it is not a type parameter
14-
--> $DIR/bad-params.rs:12:40
15-
|
16-
LL | fn self_is_not_param() -> impl use<Self> Sized {}
17-
| ^^^^ `Self` cannot be captured because it is not a type parameter
16+
| ------------ ^^^^ `Self` is only available in impls, traits, and type definitions
17+
| |
18+
| `Self` not allowed in a function
1819

1920
warning: the feature `precise_capturing` is incomplete and may not be safe to use and/or cause compiler crashes
2021
--> $DIR/bad-params.rs:1:12
@@ -25,6 +26,15 @@ LL | #![feature(precise_capturing)]
2526
= note: see issue #123432 <https://github.com/rust-lang/rust/issues/123432> for more information
2627
= note: `#[warn(incomplete_features)]` on by default
2728

29+
error: `Self` can't be captured in `use<...>` precise captures list, since it is an alias
30+
--> $DIR/bad-params.rs:12:40
31+
|
32+
LL | impl MyType {
33+
| ----------- `Self` is not a generic argument, but an alias to the type of the implementation
34+
LL | fn self_is_not_param() -> impl use<Self> Sized {}
35+
| ^^^^
36+
2837
error: aborting due to 3 previous errors; 1 warning emitted
2938

30-
For more information about this error, try `rustc --explain E0433`.
39+
Some errors have detailed explanations: E0411, E0412.
40+
For more information about an error, try `rustc --explain E0411`.

0 commit comments

Comments
 (0)