Skip to content

Commit 5377dea

Browse files
committed
Fix issue with const arg inference
1 parent f1867c5 commit 5377dea

File tree

4 files changed

+56
-11
lines changed

4 files changed

+56
-11
lines changed

src/librustc_typeck/astconv.rs

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use crate::middle::resolve_lifetime as rl;
1313
use crate::namespace::Namespace;
1414
use rustc::lint::builtin::AMBIGUOUS_ASSOCIATED_ITEMS;
1515
use rustc::traits;
16-
use rustc::ty::{self, DefIdTree, Ty, TyCtxt, ToPredicate, TypeFoldable};
16+
use rustc::ty::{self, DefIdTree, Ty, TyCtxt, Const, ToPredicate, TypeFoldable};
1717
use rustc::ty::{GenericParamDef, GenericParamDefKind};
1818
use rustc::ty::subst::{Kind, Subst, InternalSubsts, SubstsRef};
1919
use rustc::ty::wf::object_region_bounds;
@@ -61,6 +61,13 @@ pub trait AstConv<'gcx, 'tcx> {
6161
span: Span) -> Ty<'tcx> {
6262
self.ty_infer(span)
6363
}
64+
/// What const should we use when a const is omitted?
65+
fn ct_infer(
66+
&self,
67+
ty: Ty<'tcx>,
68+
param: Option<&ty::GenericParamDef>,
69+
span: Span,
70+
) -> &'tcx Const<'tcx>;
6471

6572
/// Projecting an associated type from a (potentially)
6673
/// higher-ranked trait reference is more complicated, because of
@@ -280,7 +287,6 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
280287
let param_counts = def.own_counts();
281288
let arg_counts = args.own_counts();
282289
let infer_lifetimes = position != GenericArgPosition::Type && arg_counts.lifetimes == 0;
283-
let infer_consts = position != GenericArgPosition::Type && arg_counts.consts == 0;
284290

285291
let mut defaults: ty::GenericParamCount = Default::default();
286292
for param in &def.params {
@@ -333,7 +339,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
333339
offset
334340
);
335341
// We enforce the following: `required` <= `provided` <= `permitted`.
336-
// For kinds without defaults (i.e., lifetimes), `required == permitted`.
342+
// For kinds without defaults (e.g.., lifetimes), `required == permitted`.
337343
// For other kinds (i.e., types), `permitted` may be greater than `required`.
338344
if required <= provided && provided <= permitted {
339345
return (reported_late_bound_region_err.unwrap_or(false), None);
@@ -404,7 +410,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
404410
);
405411
}
406412
// FIXME(const_generics:defaults)
407-
if !infer_consts || arg_counts.consts > param_counts.consts {
413+
if !infer_args || arg_counts.consts > param_counts.consts {
408414
check_kind_count(
409415
"const",
410416
param_counts.consts,
@@ -707,8 +713,14 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
707713
}
708714
GenericParamDefKind::Const => {
709715
// FIXME(const_generics:defaults)
710-
// We've already errored above about the mismatch.
711-
tcx.consts.err.into()
716+
if infer_args {
717+
// No const parameters were provided, we can infer all.
718+
let ty = tcx.at(span).type_of(param.def_id);
719+
self.ct_infer(ty, Some(param), span).into()
720+
} else {
721+
// We've already errored above about the mismatch.
722+
tcx.consts.err.into()
723+
}
712724
}
713725
}
714726
},

src/librustc_typeck/check/mod.rs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,11 +100,12 @@ use rustc_data_structures::indexed_vec::Idx;
100100
use rustc_target::spec::abi::Abi;
101101
use rustc::infer::opaque_types::OpaqueTypeDecl;
102102
use rustc::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
103+
use rustc::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind};
103104
use rustc::middle::region;
104105
use rustc::mir::interpret::{ConstValue, GlobalId};
105106
use rustc::traits::{self, ObligationCause, ObligationCauseCode, TraitEngine};
106107
use rustc::ty::{
107-
self, AdtKind, CanonicalUserType, Ty, TyCtxt, GenericParamDefKind, Visibility,
108+
self, AdtKind, CanonicalUserType, Ty, TyCtxt, Const, GenericParamDefKind, Visibility,
108109
ToPolyTraitRef, ToPredicate, RegionKind, UserType
109110
};
110111
use rustc::ty::adjustment::{
@@ -1959,6 +1960,22 @@ impl<'a, 'gcx, 'tcx> AstConv<'gcx, 'tcx> for FnCtxt<'a, 'gcx, 'tcx> {
19591960
span: Span) -> Ty<'tcx> {
19601961
if let UnpackedKind::Type(ty) = self.var_for_def(span, ty_param_def).unpack() {
19611962
return ty;
1963+
fn ct_infer(
1964+
&self,
1965+
ty: Ty<'tcx>,
1966+
param: Option<&ty::GenericParamDef>,
1967+
span: Span,
1968+
) -> &'tcx Const<'tcx> {
1969+
if let Some(param) = param {
1970+
if let UnpackedKind::Const(ct) = self.var_for_def(span, param).unpack() {
1971+
return ct;
1972+
}
1973+
unreachable!()
1974+
} else {
1975+
self.next_const_var(ty, ConstVariableOrigin {
1976+
kind: ConstVariableOriginKind::ConstInference,
1977+
span,
1978+
})
19621979
}
19631980
unreachable!()
19641981
}

src/librustc_typeck/collect.rs

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ use rustc::ty::subst::{Subst, InternalSubsts};
2626
use rustc::ty::util::Discr;
2727
use rustc::ty::util::IntTypeExt;
2828
use rustc::ty::subst::UnpackedKind;
29-
use rustc::ty::{self, AdtKind, DefIdTree, ToPolyTraitRef, Ty, TyCtxt};
29+
use rustc::ty::{self, AdtKind, DefIdTree, ToPolyTraitRef, Ty, TyCtxt, Const};
3030
use rustc::ty::{ReprOptions, ToPredicate};
3131
use rustc::util::captures::Captures;
3232
use rustc::util::nodemap::FxHashMap;
@@ -47,7 +47,7 @@ use rustc::hir::intravisit::{self, NestedVisitorMap, Visitor};
4747
use rustc::hir::GenericParamKind;
4848
use rustc::hir::{self, CodegenFnAttrFlags, CodegenFnAttrs, Unsafety};
4949

50-
use errors::Applicability;
50+
use errors::{Applicability, DiagnosticId};
5151

5252
use std::iter;
5353

@@ -204,6 +204,22 @@ impl<'a, 'tcx> AstConv<'tcx, 'tcx> for ItemCtxt<'a, 'tcx> {
204204
self.tcx().types.err
205205
}
206206

207+
fn ct_infer(
208+
&self,
209+
_: Ty<'tcx>,
210+
_: Option<&ty::GenericParamDef>,
211+
span: Span,
212+
) -> &'tcx Const<'tcx> {
213+
self.tcx().sess.struct_span_err_with_code(
214+
span,
215+
"the const placeholder `_` is not allowed within types on item signatures",
216+
DiagnosticId::Error("E0121".into()),
217+
).span_label(span, "not allowed in type signatures")
218+
.emit();
219+
220+
self.tcx().consts.err
221+
}
222+
207223
fn projected_ty_from_poly_trait_ref(
208224
&self,
209225
span: Span,

src/librustc_typeck/error_codes.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1482,8 +1482,8 @@ impl <'a> Drop for MyWrapper<'a> {
14821482
"##,
14831483

14841484
E0121: r##"
1485-
In order to be consistent with Rust's lack of global type inference, type
1486-
placeholders are disallowed by design in item signatures.
1485+
In order to be consistent with Rust's lack of global type inference,
1486+
type and const placeholders are disallowed by design in item signatures.
14871487
14881488
Examples of this error include:
14891489

0 commit comments

Comments
 (0)