Skip to content

Commit e154b64

Browse files
Use a path instead of an ident (and stop manually resolving)
1 parent e6dc0de commit e154b64

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
@@ -2191,12 +2191,12 @@ pub enum TraitObjectSyntax {
21912191
None,
21922192
}
21932193

2194-
#[derive(Clone, PartialEq, Encodable, Decodable, Debug)]
2194+
#[derive(Clone, Encodable, Decodable, Debug)]
21952195
pub enum PreciseCapturingArg {
21962196
/// Lifetime parameter
21972197
Lifetime(Lifetime),
21982198
/// Type or const parameter
2199-
Arg(Ident, NodeId),
2199+
Arg(Path, NodeId),
22002200
}
22012201

22022202
/// 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
@@ -924,8 +924,8 @@ pub fn noop_visit_precise_capturing_arg<T: MutVisitor>(arg: &mut PreciseCapturin
924924
PreciseCapturingArg::Lifetime(lt) => {
925925
vis.visit_lifetime(lt);
926926
}
927-
PreciseCapturingArg::Arg(ident, id) => {
928-
vis.visit_ident(ident);
927+
PreciseCapturingArg::Arg(path, id) => {
928+
vis.visit_path(path);
929929
vis.visit_id(id);
930930
}
931931
}

compiler/rustc_ast/src/visit.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -649,8 +649,8 @@ pub fn walk_precise_capturing_arg<'a, V: Visitor<'a>>(
649649
PreciseCapturingArg::Lifetime(lt) => {
650650
visitor.visit_lifetime(lt, LifetimeCtxt::GenericArg);
651651
}
652-
PreciseCapturingArg::Arg(ident, _) => {
653-
visitor.visit_ident(*ident);
652+
PreciseCapturingArg::Arg(path, id) => {
653+
visitor.visit_path(path, *id);
654654
}
655655
}
656656
}

compiler/rustc_ast_lowering/src/lib.rs

+7-4
Original file line numberDiff line numberDiff line change
@@ -1787,13 +1787,16 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
17871787
PreciseCapturingArg::Lifetime(lt) => {
17881788
hir::PreciseCapturingArg::Lifetime(self.lower_lifetime(lt))
17891789
}
1790-
PreciseCapturingArg::Arg(ident, node_id) => {
1791-
let res = self.resolver.get_partial_res(*node_id).map_or(Res::Err, |partial_res| {
1790+
PreciseCapturingArg::Arg(path, id) => {
1791+
let [segment] = path.segments.as_slice() else {
1792+
panic!();
1793+
};
1794+
let res = self.resolver.get_partial_res(*id).map_or(Res::Err, |partial_res| {
17921795
partial_res.full_res().expect("no partial res expected for precise capture arg")
17931796
});
17941797
hir::PreciseCapturingArg::Param(hir::PreciseCapturingNonLifetimeArg {
1795-
hir_id: self.lower_node_id(*node_id),
1796-
ident: self.lower_ident(*ident),
1798+
hir_id: self.lower_node_id(*id),
1799+
ident: self.lower_ident(segment.ident),
17971800
res: self.lower_res(res),
17981801
})
17991802
}

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

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
@@ -1059,64 +1059,22 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast,
10591059
match arg {
10601060
// Lower the lifetime regularly; we'll resolve the lifetime and check
10611061
// it's a parameter later on in HIR lowering.
1062-
PreciseCapturingArg::Lifetime(_) => visit::walk_precise_capturing_arg(self, arg),
1062+
PreciseCapturingArg::Lifetime(_) => {}
10631063

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

11221080
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)