Skip to content
Permalink
Browse files

Fix issue with const arg inference

  • Loading branch information...
varkor committed Jun 6, 2019
1 parent f1867c5 commit 5377dea7fc8dc1f05ddc4c444fddf1994293bfeb
@@ -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:

0 comments on commit 5377dea

Please sign in to comment.
You can’t perform that action at this time.