Fix issue with const arg inference
This commit is contained in:
parent
f1867c5497
commit
5377dea7fc
4 changed files with 56 additions and 11 deletions
|
@ -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()
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
@ -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!()
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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:
|
||||
|
||||
|
|
Loading…
Reference in a new issue