Skip to content

Commit 2bcc43c

Browse files
yodaldevoidvarkor
andcommitted
Make sure places where Generics::own_counts was called took consts into account
Signed-off-by: Gabriel Smith <[email protected]> Co-authored-by: varkor <[email protected]>
1 parent eaa393c commit 2bcc43c

File tree

9 files changed

+105
-15
lines changed

9 files changed

+105
-15
lines changed

src/librustc/hir/map/mod.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,11 @@ impl<'hir> MapEntry<'hir> {
241241
}
242242
}
243243

244+
EntryGenericParam(_, _, _) => {
245+
// TODO(const_generics): defaults
246+
None
247+
}
248+
244249
_ => None
245250
}
246251
}

src/librustc/middle/resolve_lifetime.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1368,7 +1368,8 @@ fn object_lifetime_defaults_for_item(
13681368
})
13691369
}
13701370
GenericParamKind::Const { .. } => {
1371-
unimplemented!() // TODO(const_generics):
1371+
// TODO(const_generics):
1372+
None
13721373
}
13731374
})
13741375
.collect()

src/librustc/ty/flags.rs

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -235,10 +235,16 @@ impl FlagComputation {
235235

236236
fn add_const(&mut self, constant: &ty::Const) {
237237
self.add_ty(constant.ty);
238-
// TODO(const_generics): `Param`
239-
if let ConstValue::Unevaluated(_, substs) = constant.val {
240-
self.add_flags(TypeFlags::HAS_PROJECTION);
241-
self.add_substs(substs);
238+
match constant.val {
239+
ConstValue::Unevaluated(_, substs) => {
240+
self.add_flags(TypeFlags::HAS_PROJECTION);
241+
self.add_substs(substs);
242+
}
243+
ConstVal::Param(_) => {
244+
self.add_flags(TypeFlags::HAS_FREE_LOCAL_NAMES);
245+
self.add_flags(TypeFlags::HAS_PARAMS);
246+
}
247+
_ => {}
242248
}
243249
}
244250

src/librustc/ty/mod.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -918,7 +918,6 @@ impl<'a, 'gcx, 'tcx> Generics<'tcx> {
918918
self.parent_count + self.params.len()
919919
}
920920

921-
// TODO(const_generics): check uses for places where consts need to be taken into account
922921
pub fn own_counts(&self) -> GenericParamCount {
923922
// We could cache this as a property of `GenericParamCount`, but
924923
// the aim is to refactor this away entirely eventually and the

src/librustc_mir/monomorphize/collector.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1116,7 +1116,8 @@ fn create_mono_items_for_default_impls<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
11161116
continue;
11171117
}
11181118

1119-
if tcx.generics_of(method.def_id).own_counts().types != 0 {
1119+
let counts = tcx.generics_of(method.def_id).own_counts();
1120+
if counts.types + counts.consts != 0 {
11201121
continue;
11211122
}
11221123

src/librustc_mir/transform/check_unsafety.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -386,9 +386,10 @@ fn unsafe_derive_on_repr_packed<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: D
386386

387387
// FIXME: when we make this a hard error, this should have its
388388
// own error code.
389-
let message = if tcx.generics_of(def_id).own_counts().types != 0 {
389+
let counts = tcx.generics_of(def_id).own_counts();
390+
let message = if counts.types + counts.consts != 0 {
390391
"#[derive] can't be used on a #[repr(packed)] struct with \
391-
type parameters (error E0133)".to_string()
392+
type or const parameters (error E0133)".to_string()
392393
} else {
393394
"#[derive] can't be used on a #[repr(packed)] struct that \
394395
does not derive Copy (error E0133)".to_string()

src/librustc_typeck/check/compare_method.rs

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -641,6 +641,61 @@ fn compare_number_of_generics<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
641641
return Err(ErrorReported);
642642
}
643643

644+
let num_impl_m_const_params = impl_m_generics.own_counts().consts;
645+
let num_trait_m_const_params = trait_m_generics.own_counts().consts;
646+
647+
if num_impl_m_const_params != num_trait_m_const_params {
648+
let impl_m_node_id = tcx.hir.as_local_node_id(impl_m.def_id).unwrap();
649+
let impl_m_item = tcx.hir.expect_impl_item(impl_m_node_id);
650+
let span = if impl_m_item.generics.params.is_empty() {
651+
impl_m_span
652+
} else {
653+
impl_m_item.generics.span
654+
};
655+
656+
let mut err = struct_span_err!(tcx.sess,
657+
span,
658+
E0049, // TDOO(const_generics): new error code?
659+
"method `{}` has {} const parameter{} but its trait \
660+
declaration has {} const parameter{}",
661+
trait_m.name,
662+
num_impl_m_const_params,
663+
if num_impl_m_const_params == 1 { "" } else { "s" },
664+
num_trait_m_const_params,
665+
if num_trait_m_const_params == 1 {
666+
""
667+
} else {
668+
"s"
669+
});
670+
671+
let mut suffix = None;
672+
673+
if let Some(span) = trait_item_span {
674+
err.span_label(span,
675+
format!("expected {}",
676+
&if num_trait_m_const_params != 1 {
677+
format!("{} const parameters", num_trait_m_const_params)
678+
} else {
679+
format!("{} const parameter", num_trait_m_const_params)
680+
}));
681+
} else {
682+
suffix = Some(format!(", expected {}", num_trait_m_const_params));
683+
}
684+
685+
err.span_label(span,
686+
format!("found {}{}",
687+
&if num_impl_m_const_params != 1 {
688+
format!("{} const parameters", num_impl_m_const_params)
689+
} else {
690+
format!("1 const parameter")
691+
},
692+
suffix.as_ref().map(|s| &s[..]).unwrap_or("")));
693+
694+
err.emit();
695+
696+
return Err(ErrorReported);
697+
}
698+
644699
Ok(())
645700
}
646701

src/librustc_typeck/check/mod.rs

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1332,10 +1332,11 @@ pub fn check_item_type<'a,'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, it: &'tcx hir::Item
13321332
let generics = tcx.generics_of(tcx.hir.local_def_id(item.id));
13331333
if generics.params.len() - generics.own_counts().lifetimes != 0 {
13341334
let mut err = struct_span_err!(tcx.sess, item.span, E0044,
1335-
"foreign items may not have type parameters");
1336-
err.span_label(item.span, "can't have type parameters");
1335+
"foreign items may not have type or const parameters");
1336+
err.span_label(item.span, "can't have type or const parameters");
13371337
// FIXME: once we start storing spans for type arguments, turn this into a
13381338
// suggestion.
1339+
// TODO(const_generics): help message
13391340
err.help("use specialization instead of type parameters by replacing them \
13401341
with concrete types like `u32`");
13411342
err.emit();
@@ -5161,14 +5162,17 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
51615162
}
51625163
}
51635164

5164-
//TODO: Const Params
51655165
pub fn check_bounds_are_used<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
51665166
generics: &ty::Generics,
51675167
ty: Ty<'tcx>) {
51685168
let own_counts = generics.own_counts();
5169-
debug!("check_bounds_are_used(n_tps={}, ty={:?})", own_counts.types, ty);
5169+
debug!("check_bounds_are_used(n_tps={}, n_cts={}, ty={:?})",
5170+
own_counts.types,
5171+
own_counts.consts,
5172+
ty
5173+
);
51705174

5171-
if own_counts.types == 0 {
5175+
if own_counts.types + own_counts.consts == 0 {
51725176
return;
51735177
}
51745178
// Make a vector of booleans initially false, set to true when used.
@@ -5199,6 +5203,24 @@ pub fn check_bounds_are_used<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
51995203
.emit();
52005204
}
52015205
}
5206+
5207+
// TODO(const_generics): is there even a way to walk all consts?
5208+
//let mut consts_used = vec![false; own_counts.types];
5209+
//
5210+
//let consts = generics.params.iter().filter(|param| match param.kind {
5211+
// ty::GenericParamDefKind::Const { .. } => true,
5212+
// _ => false,
5213+
//});
5214+
//for (&used, param) in consts_used.iter().zip(consts) {
5215+
// if !used {
5216+
// let id = tcx.hir.as_local_node_id(param.def_id).unwrap();
5217+
// let span = tcx.hir.span(id);
5218+
// // TODO(const_generics): new error code
5219+
// struct_span_err!(tcx.sess, span, E0091, "const parameter `{}` is unused", param.name)
5220+
// .span_label(span, "unused const parameter")
5221+
// .emit();
5222+
// }
5223+
//}
52025224
}
52035225

52045226
fn fatally_break_rust(sess: &Session) {

src/librustc_typeck/diagnostics.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -431,7 +431,7 @@ impl Foo for Bar {
431431

432432
E0049: r##"
433433
This error indicates that an attempted implementation of a trait method
434-
has the wrong number of type parameters.
434+
has the wrong number of type or const parameters.
435435
436436
For example, the trait below has a method `foo` with a type parameter `T`,
437437
but the implementation of `foo` for the type `Bar` is missing this parameter:

0 commit comments

Comments
 (0)