Fix issue with const arg inference

This commit is contained in:
varkor 2019-06-06 01:55:09 +01:00
parent f1867c5497
commit 5377dea7fc
4 changed files with 56 additions and 11 deletions

View file

@ -13,7 +13,7 @@ use crate::middle::resolve_lifetime as rl;
use crate::namespace::Namespace;
use rustc::lint::builtin::AMBIGUOUS_ASSOCIATED_ITEMS;
use rustc::traits;
use rustc::ty::{self, DefIdTree, Ty, TyCtxt, ToPredicate, TypeFoldable};
use rustc::ty::{self, DefIdTree, Ty, TyCtxt, Const, ToPredicate, TypeFoldable};
use rustc::ty::{GenericParamDef, GenericParamDefKind};
use rustc::ty::subst::{Kind, Subst, InternalSubsts, SubstsRef};
use rustc::ty::wf::object_region_bounds;
@ -61,6 +61,13 @@ pub trait AstConv<'gcx, 'tcx> {
span: Span) -> Ty<'tcx> {
self.ty_infer(span)
}
/// What const should we use when a const is omitted?
fn ct_infer(
&self,
ty: Ty<'tcx>,
param: Option<&ty::GenericParamDef>,
span: Span,
) -> &'tcx Const<'tcx>;
/// Projecting an associated type from a (potentially)
/// higher-ranked trait reference is more complicated, because of
@ -280,7 +287,6 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
let param_counts = def.own_counts();
let arg_counts = args.own_counts();
let infer_lifetimes = position != GenericArgPosition::Type && arg_counts.lifetimes == 0;
let infer_consts = position != GenericArgPosition::Type && arg_counts.consts == 0;
let mut defaults: ty::GenericParamCount = Default::default();
for param in &def.params {
@ -333,7 +339,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
offset
);
// We enforce the following: `required` <= `provided` <= `permitted`.
// For kinds without defaults (i.e., lifetimes), `required == permitted`.
// For kinds without defaults (e.g.., lifetimes), `required == permitted`.
// For other kinds (i.e., types), `permitted` may be greater than `required`.
if required <= provided && provided <= permitted {
return (reported_late_bound_region_err.unwrap_or(false), None);
@ -404,7 +410,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
);
}
// FIXME(const_generics:defaults)
if !infer_consts || arg_counts.consts > param_counts.consts {
if !infer_args || arg_counts.consts > param_counts.consts {
check_kind_count(
"const",
param_counts.consts,
@ -707,8 +713,14 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
}
GenericParamDefKind::Const => {
// FIXME(const_generics:defaults)
// We've already errored above about the mismatch.
tcx.consts.err.into()
if infer_args {
// No const parameters were provided, we can infer all.
let ty = tcx.at(span).type_of(param.def_id);
self.ct_infer(ty, Some(param), span).into()
} else {
// We've already errored above about the mismatch.
tcx.consts.err.into()
}
}
}
},

View file

@ -100,11 +100,12 @@ use rustc_data_structures::indexed_vec::Idx;
use rustc_target::spec::abi::Abi;
use rustc::infer::opaque_types::OpaqueTypeDecl;
use rustc::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
use rustc::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind};
use rustc::middle::region;
use rustc::mir::interpret::{ConstValue, GlobalId};
use rustc::traits::{self, ObligationCause, ObligationCauseCode, TraitEngine};
use rustc::ty::{
self, AdtKind, CanonicalUserType, Ty, TyCtxt, GenericParamDefKind, Visibility,
self, AdtKind, CanonicalUserType, Ty, TyCtxt, Const, GenericParamDefKind, Visibility,
ToPolyTraitRef, ToPredicate, RegionKind, UserType
};
use rustc::ty::adjustment::{
@ -1959,6 +1960,22 @@ impl<'a, 'gcx, 'tcx> AstConv<'gcx, 'tcx> for FnCtxt<'a, 'gcx, 'tcx> {
span: Span) -> Ty<'tcx> {
if let UnpackedKind::Type(ty) = self.var_for_def(span, ty_param_def).unpack() {
return ty;
fn ct_infer(
&self,
ty: Ty<'tcx>,
param: Option<&ty::GenericParamDef>,
span: Span,
) -> &'tcx Const<'tcx> {
if let Some(param) = param {
if let UnpackedKind::Const(ct) = self.var_for_def(span, param).unpack() {
return ct;
}
unreachable!()
} else {
self.next_const_var(ty, ConstVariableOrigin {
kind: ConstVariableOriginKind::ConstInference,
span,
})
}
unreachable!()
}

View file

@ -26,7 +26,7 @@ use rustc::ty::subst::{Subst, InternalSubsts};
use rustc::ty::util::Discr;
use rustc::ty::util::IntTypeExt;
use rustc::ty::subst::UnpackedKind;
use rustc::ty::{self, AdtKind, DefIdTree, ToPolyTraitRef, Ty, TyCtxt};
use rustc::ty::{self, AdtKind, DefIdTree, ToPolyTraitRef, Ty, TyCtxt, Const};
use rustc::ty::{ReprOptions, ToPredicate};
use rustc::util::captures::Captures;
use rustc::util::nodemap::FxHashMap;
@ -47,7 +47,7 @@ use rustc::hir::intravisit::{self, NestedVisitorMap, Visitor};
use rustc::hir::GenericParamKind;
use rustc::hir::{self, CodegenFnAttrFlags, CodegenFnAttrs, Unsafety};
use errors::Applicability;
use errors::{Applicability, DiagnosticId};
use std::iter;
@ -204,6 +204,22 @@ impl<'a, 'tcx> AstConv<'tcx, 'tcx> for ItemCtxt<'a, 'tcx> {
self.tcx().types.err
}
fn ct_infer(
&self,
_: Ty<'tcx>,
_: Option<&ty::GenericParamDef>,
span: Span,
) -> &'tcx Const<'tcx> {
self.tcx().sess.struct_span_err_with_code(
span,
"the const placeholder `_` is not allowed within types on item signatures",
DiagnosticId::Error("E0121".into()),
).span_label(span, "not allowed in type signatures")
.emit();
self.tcx().consts.err
}
fn projected_ty_from_poly_trait_ref(
&self,
span: Span,

View file

@ -1482,8 +1482,8 @@ impl <'a> Drop for MyWrapper<'a> {
"##,
E0121: r##"
In order to be consistent with Rust's lack of global type inference, type
placeholders are disallowed by design in item signatures.
In order to be consistent with Rust's lack of global type inference,
type and const placeholders are disallowed by design in item signatures.
Examples of this error include: