Skip to content

Commit 73945fd

Browse files
committed
fix bug
1 parent 22e491a commit 73945fd

File tree

5 files changed

+51
-46
lines changed

5 files changed

+51
-46
lines changed

compiler/rustc_hir/src/hir.rs

-4
Original file line numberDiff line numberDiff line change
@@ -293,10 +293,6 @@ impl GenericArg<'_> {
293293
}
294294
}
295295

296-
pub fn is_const(&self) -> bool {
297-
matches!(self, GenericArg::Const(_))
298-
}
299-
300296
pub fn is_synthetic(&self) -> bool {
301297
matches!(self, GenericArg::Lifetime(lifetime) if lifetime.name.ident() == Ident::empty())
302298
}

compiler/rustc_typeck/src/collect/type_of.rs

+36-31
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ use super::{bad_placeholder, is_suggestable_infer_ty};
1818
/// Computes the relevant generic parameter for a potential generic const argument.
1919
///
2020
/// This should be called using the query `tcx.opt_const_param_of`.
21+
#[instrument(level = "debug", skip(tcx))]
2122
pub(super) fn opt_const_param_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<DefId> {
2223
// FIXME(generic_arg_infer): allow for returning DefIds of inference of
2324
// GenericArg::Infer below. This may require a change where GenericArg::Infer has some flag
@@ -29,7 +30,7 @@ pub(super) fn opt_const_param_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<
2930
let parent_node_id = tcx.hir().get_parent_node(hir_id);
3031
let parent_node = tcx.hir().get(parent_node_id);
3132

32-
match parent_node {
33+
let (generics, arg_idx) = match parent_node {
3334
// This match arm is for when the def_id appears in a GAT whose
3435
// path can't be resolved without typechecking e.g.
3536
//
@@ -75,27 +76,22 @@ pub(super) fn opt_const_param_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<
7576
.and_then(|args| {
7677
args.args
7778
.iter()
78-
.filter(|arg| arg.is_const())
79+
.filter(|arg| !matches!(arg, GenericArg::Lifetime(_)))
7980
.position(|arg| arg.id() == hir_id)
8081
})
8182
.unwrap_or_else(|| {
8283
bug!("no arg matching AnonConst in segment");
8384
});
8485

85-
return generics
86-
.params
87-
.iter()
88-
.filter(|param| matches!(param.kind, ty::GenericParamDefKind::Const { .. }))
89-
.nth(arg_index)
90-
.map(|param| param.def_id);
86+
(generics, arg_index)
87+
} else {
88+
// I dont think it's possible to reach this but I'm not 100% sure - BoxyUwU
89+
tcx.sess.delay_span_bug(
90+
tcx.def_span(def_id),
91+
"unexpected non-GAT usage of an anon const",
92+
);
93+
return None;
9194
}
92-
93-
// I dont think it's possible to reach this but I'm not 100% sure - BoxyUwU
94-
tcx.sess.delay_span_bug(
95-
tcx.def_span(def_id),
96-
"unexpected non-GAT usage of an anon const",
97-
);
98-
return None;
9995
}
10096
Node::Expr(&Expr {
10197
kind:
@@ -113,19 +109,14 @@ pub(super) fn opt_const_param_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<
113109
.and_then(|args| {
114110
args.args
115111
.iter()
116-
.filter(|arg| arg.is_const())
112+
.filter(|arg| !matches!(arg, GenericArg::Lifetime(_)))
117113
.position(|arg| arg.id() == hir_id)
118114
})
119115
.unwrap_or_else(|| {
120116
bug!("no arg matching AnonConst in segment");
121117
});
122118

123-
tcx.generics_of(type_dependent_def)
124-
.params
125-
.iter()
126-
.filter(|param| matches!(param.kind, ty::GenericParamDefKind::Const { .. }))
127-
.nth(idx)
128-
.map(|param| param.def_id)
119+
(tcx.generics_of(type_dependent_def), idx)
129120
}
130121

131122
Node::Ty(&Ty { kind: TyKind::Path(_), .. })
@@ -178,7 +169,7 @@ pub(super) fn opt_const_param_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<
178169
.filter_map(|seg| seg.args.map(|args| (args.args, seg)))
179170
.find_map(|(args, seg)| {
180171
args.iter()
181-
.filter(|arg| arg.is_const())
172+
.filter(|arg| !matches!(arg, GenericArg::Lifetime(_)))
182173
.position(|arg| arg.id() == hir_id)
183174
.map(|index| (index, seg))
184175
});
@@ -238,15 +229,29 @@ pub(super) fn opt_const_param_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<
238229
}
239230
};
240231

241-
generics
242-
.params
243-
.iter()
244-
.filter(|param| matches!(param.kind, ty::GenericParamDefKind::Const { .. }))
245-
.nth(arg_index)
246-
.map(|param| param.def_id)
232+
(generics, arg_index)
247233
}
248-
_ => None,
249-
}
234+
_ => return None,
235+
};
236+
237+
debug!(?parent_node);
238+
debug!(?generics);
239+
debug!(?arg_idx);
240+
generics
241+
.params
242+
.iter()
243+
.filter(|param| !matches!(param.kind, ty::GenericParamDefKind::Lifetime { .. }))
244+
.nth(match generics.has_self && generics.parent.is_none() {
245+
true => arg_idx + 1,
246+
false => arg_idx,
247+
})
248+
.and_then(|param| match param.kind {
249+
ty::GenericParamDefKind::Const { .. } => {
250+
debug!(?param);
251+
Some(param.def_id)
252+
}
253+
_ => None,
254+
})
250255
} else {
251256
None
252257
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// check-pass
2+
#![feature(generic_arg_infer)]
3+
4+
struct Foo<const N: bool, const M: u8>;
5+
struct Bar<const N: u8, const M: u32>;
6+
7+
fn main() {
8+
let _: Foo<true, _> = Foo::<_, 1>;
9+
let _: Foo<_, 1> = Foo::<true, _>;
10+
let _: Bar<1, _> = Bar::<_, 300>;
11+
let _: Bar<_, 300> = Bar::<1, _>;
12+
}

src/test/ui/const-generics/issues/issue-62878.full.stderr

+2-9
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,6 @@ error[E0770]: the type of const parameters must not depend on other generic para
44
LL | fn foo<const N: usize, const A: [u8; N]>() {}
55
| ^ the type must not depend on the parameter `N`
66

7-
error[E0308]: mismatched types
8-
--> $DIR/issue-62878.rs:10:15
9-
|
10-
LL | foo::<_, {[1]}>();
11-
| ^^^ expected `usize`, found array `[{integer}; 1]`
12-
13-
error: aborting due to 2 previous errors
7+
error: aborting due to previous error
148

15-
Some errors have detailed explanations: E0308, E0770.
16-
For more information about an error, try `rustc --explain E0308`.
9+
For more information about this error, try `rustc --explain E0770`.

src/test/ui/const-generics/issues/issue-62878.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,5 @@ fn foo<const N: usize, const A: [u8; N]>() {}
77
//[min]~| ERROR `[u8; _]` is forbidden as the type of a const generic parameter
88

99
fn main() {
10-
foo::<_, {[1]}>();
11-
//[full]~^ ERROR mismatched types
10+
foo::<_, { [1] }>();
1211
}

0 commit comments

Comments
 (0)