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 crate::namespace::Namespace;
|
||||||
use rustc::lint::builtin::AMBIGUOUS_ASSOCIATED_ITEMS;
|
use rustc::lint::builtin::AMBIGUOUS_ASSOCIATED_ITEMS;
|
||||||
use rustc::traits;
|
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::{GenericParamDef, GenericParamDefKind};
|
||||||
use rustc::ty::subst::{Kind, Subst, InternalSubsts, SubstsRef};
|
use rustc::ty::subst::{Kind, Subst, InternalSubsts, SubstsRef};
|
||||||
use rustc::ty::wf::object_region_bounds;
|
use rustc::ty::wf::object_region_bounds;
|
||||||
|
@ -61,6 +61,13 @@ pub trait AstConv<'gcx, 'tcx> {
|
||||||
span: Span) -> Ty<'tcx> {
|
span: Span) -> Ty<'tcx> {
|
||||||
self.ty_infer(span)
|
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)
|
/// Projecting an associated type from a (potentially)
|
||||||
/// higher-ranked trait reference is more complicated, because of
|
/// 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 param_counts = def.own_counts();
|
||||||
let arg_counts = args.own_counts();
|
let arg_counts = args.own_counts();
|
||||||
let infer_lifetimes = position != GenericArgPosition::Type && arg_counts.lifetimes == 0;
|
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();
|
let mut defaults: ty::GenericParamCount = Default::default();
|
||||||
for param in &def.params {
|
for param in &def.params {
|
||||||
|
@ -333,7 +339,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
|
||||||
offset
|
offset
|
||||||
);
|
);
|
||||||
// We enforce the following: `required` <= `provided` <= `permitted`.
|
// 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`.
|
// For other kinds (i.e., types), `permitted` may be greater than `required`.
|
||||||
if required <= provided && provided <= permitted {
|
if required <= provided && provided <= permitted {
|
||||||
return (reported_late_bound_region_err.unwrap_or(false), None);
|
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)
|
// 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(
|
check_kind_count(
|
||||||
"const",
|
"const",
|
||||||
param_counts.consts,
|
param_counts.consts,
|
||||||
|
@ -707,8 +713,14 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
|
||||||
}
|
}
|
||||||
GenericParamDefKind::Const => {
|
GenericParamDefKind::Const => {
|
||||||
// FIXME(const_generics:defaults)
|
// FIXME(const_generics:defaults)
|
||||||
// We've already errored above about the mismatch.
|
if infer_args {
|
||||||
tcx.consts.err.into()
|
// 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_target::spec::abi::Abi;
|
||||||
use rustc::infer::opaque_types::OpaqueTypeDecl;
|
use rustc::infer::opaque_types::OpaqueTypeDecl;
|
||||||
use rustc::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
|
use rustc::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
|
||||||
|
use rustc::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind};
|
||||||
use rustc::middle::region;
|
use rustc::middle::region;
|
||||||
use rustc::mir::interpret::{ConstValue, GlobalId};
|
use rustc::mir::interpret::{ConstValue, GlobalId};
|
||||||
use rustc::traits::{self, ObligationCause, ObligationCauseCode, TraitEngine};
|
use rustc::traits::{self, ObligationCause, ObligationCauseCode, TraitEngine};
|
||||||
use rustc::ty::{
|
use rustc::ty::{
|
||||||
self, AdtKind, CanonicalUserType, Ty, TyCtxt, GenericParamDefKind, Visibility,
|
self, AdtKind, CanonicalUserType, Ty, TyCtxt, Const, GenericParamDefKind, Visibility,
|
||||||
ToPolyTraitRef, ToPredicate, RegionKind, UserType
|
ToPolyTraitRef, ToPredicate, RegionKind, UserType
|
||||||
};
|
};
|
||||||
use rustc::ty::adjustment::{
|
use rustc::ty::adjustment::{
|
||||||
|
@ -1959,6 +1960,22 @@ impl<'a, 'gcx, 'tcx> AstConv<'gcx, 'tcx> for FnCtxt<'a, 'gcx, 'tcx> {
|
||||||
span: Span) -> Ty<'tcx> {
|
span: Span) -> Ty<'tcx> {
|
||||||
if let UnpackedKind::Type(ty) = self.var_for_def(span, ty_param_def).unpack() {
|
if let UnpackedKind::Type(ty) = self.var_for_def(span, ty_param_def).unpack() {
|
||||||
return ty;
|
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!()
|
unreachable!()
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,7 @@ use rustc::ty::subst::{Subst, InternalSubsts};
|
||||||
use rustc::ty::util::Discr;
|
use rustc::ty::util::Discr;
|
||||||
use rustc::ty::util::IntTypeExt;
|
use rustc::ty::util::IntTypeExt;
|
||||||
use rustc::ty::subst::UnpackedKind;
|
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::ty::{ReprOptions, ToPredicate};
|
||||||
use rustc::util::captures::Captures;
|
use rustc::util::captures::Captures;
|
||||||
use rustc::util::nodemap::FxHashMap;
|
use rustc::util::nodemap::FxHashMap;
|
||||||
|
@ -47,7 +47,7 @@ use rustc::hir::intravisit::{self, NestedVisitorMap, Visitor};
|
||||||
use rustc::hir::GenericParamKind;
|
use rustc::hir::GenericParamKind;
|
||||||
use rustc::hir::{self, CodegenFnAttrFlags, CodegenFnAttrs, Unsafety};
|
use rustc::hir::{self, CodegenFnAttrFlags, CodegenFnAttrs, Unsafety};
|
||||||
|
|
||||||
use errors::Applicability;
|
use errors::{Applicability, DiagnosticId};
|
||||||
|
|
||||||
use std::iter;
|
use std::iter;
|
||||||
|
|
||||||
|
@ -204,6 +204,22 @@ impl<'a, 'tcx> AstConv<'tcx, 'tcx> for ItemCtxt<'a, 'tcx> {
|
||||||
self.tcx().types.err
|
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(
|
fn projected_ty_from_poly_trait_ref(
|
||||||
&self,
|
&self,
|
||||||
span: Span,
|
span: Span,
|
||||||
|
|
|
@ -1482,8 +1482,8 @@ impl <'a> Drop for MyWrapper<'a> {
|
||||||
"##,
|
"##,
|
||||||
|
|
||||||
E0121: r##"
|
E0121: r##"
|
||||||
In order to be consistent with Rust's lack of global type inference, type
|
In order to be consistent with Rust's lack of global type inference,
|
||||||
placeholders are disallowed by design in item signatures.
|
type and const placeholders are disallowed by design in item signatures.
|
||||||
|
|
||||||
Examples of this error include:
|
Examples of this error include:
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue