Auto merge of #60508 - varkor:const-generics-fold-ct-err, r=petrochenkov
Fix substs issues for const errors Fixes https://github.com/rust-lang/rust/issues/60503.
This commit is contained in:
commit
c55b68aaef
@ -550,17 +550,32 @@ impl<'a, 'gcx, 'tcx> SubstFolder<'a, 'gcx, 'tcx> {
|
||||
let opt_ty = self.substs.get(p.idx as usize).map(|k| k.unpack());
|
||||
let ty = match opt_ty {
|
||||
Some(UnpackedKind::Type(ty)) => ty,
|
||||
_ => {
|
||||
Some(kind) => {
|
||||
let span = self.span.unwrap_or(DUMMY_SP);
|
||||
span_bug!(
|
||||
span,
|
||||
"Type parameter `{:?}` ({:?}/{}) out of range \
|
||||
"expected type for `{:?}` ({:?}/{}) but found {:?} \
|
||||
when substituting (root type={:?}) substs={:?}",
|
||||
p,
|
||||
source_ty,
|
||||
p.idx,
|
||||
kind,
|
||||
self.root_ty,
|
||||
self.substs,
|
||||
);
|
||||
}
|
||||
None => {
|
||||
let span = self.span.unwrap_or(DUMMY_SP);
|
||||
span_bug!(
|
||||
span,
|
||||
"type parameter `{:?}` ({:?}/{}) out of range \
|
||||
when substituting (root type={:?}) substs={:?}",
|
||||
p,
|
||||
source_ty,
|
||||
p.idx,
|
||||
self.root_ty,
|
||||
self.substs);
|
||||
self.substs,
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
@ -570,29 +585,41 @@ impl<'a, 'gcx, 'tcx> SubstFolder<'a, 'gcx, 'tcx> {
|
||||
fn const_for_param(
|
||||
&self,
|
||||
p: ParamConst,
|
||||
source_cn: &'tcx ty::Const<'tcx>
|
||||
source_ct: &'tcx ty::Const<'tcx>
|
||||
) -> &'tcx ty::Const<'tcx> {
|
||||
// Look up the const in the substitutions. It really should be in there.
|
||||
let opt_cn = self.substs.get(p.index as usize).map(|k| k.unpack());
|
||||
let cn = match opt_cn {
|
||||
Some(UnpackedKind::Const(cn)) => cn,
|
||||
_ => {
|
||||
let opt_ct = self.substs.get(p.index as usize).map(|k| k.unpack());
|
||||
let ct = match opt_ct {
|
||||
Some(UnpackedKind::Const(ct)) => ct,
|
||||
Some(kind) => {
|
||||
let span = self.span.unwrap_or(DUMMY_SP);
|
||||
span_bug!(
|
||||
span,
|
||||
"Const parameter `{:?}` ({:?}/{}) out of range \
|
||||
when substituting (root type={:?}) substs={:?}",
|
||||
"expected const for `{:?}` ({:?}/{}) but found {:?} \
|
||||
when substituting substs={:?}",
|
||||
p,
|
||||
source_cn,
|
||||
source_ct,
|
||||
p.index,
|
||||
kind,
|
||||
self.substs,
|
||||
);
|
||||
}
|
||||
None => {
|
||||
let span = self.span.unwrap_or(DUMMY_SP);
|
||||
span_bug!(
|
||||
span,
|
||||
"const parameter `{:?}` ({:?}/{}) out of range \
|
||||
when substituting substs={:?}",
|
||||
p,
|
||||
source_ct,
|
||||
p.index,
|
||||
self.root_ty,
|
||||
self.substs,
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
// FIXME(const_generics): shift const through binders
|
||||
cn
|
||||
ct
|
||||
}
|
||||
|
||||
/// It is sometimes necessary to adjust the De Bruijn indices during substitution. This occurs
|
||||
|
@ -21,7 +21,7 @@ use syntax::visit::{self, Visitor};
|
||||
use syntax::{span_err, struct_span_err, walk_list};
|
||||
use syntax_ext::proc_macro_decls::is_proc_macro_attr;
|
||||
use syntax_pos::{Span, MultiSpan};
|
||||
use errors::Applicability;
|
||||
use errors::{Applicability, FatalError};
|
||||
use log::debug;
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
@ -368,6 +368,8 @@ fn validate_generics_order<'a>(
|
||||
let mut max_param: Option<ParamKindOrd> = None;
|
||||
let mut out_of_order = FxHashMap::default();
|
||||
let mut param_idents = vec![];
|
||||
let mut found_type = false;
|
||||
let mut found_const = false;
|
||||
|
||||
for (kind, bounds, span, ident) in generics {
|
||||
if let Some(ident) = ident {
|
||||
@ -381,6 +383,11 @@ fn validate_generics_order<'a>(
|
||||
}
|
||||
Some(_) | None => *max_param = Some(kind),
|
||||
};
|
||||
match kind {
|
||||
ParamKindOrd::Type => found_type = true,
|
||||
ParamKindOrd::Const => found_const = true,
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
let mut ordered_params = "<".to_string();
|
||||
@ -408,8 +415,8 @@ fn validate_generics_order<'a>(
|
||||
GenericPosition::Arg => "argument",
|
||||
};
|
||||
|
||||
for (param_ord, (max_param, spans)) in out_of_order {
|
||||
let mut err = handler.struct_span_err(spans,
|
||||
for (param_ord, (max_param, spans)) in &out_of_order {
|
||||
let mut err = handler.struct_span_err(spans.clone(),
|
||||
&format!(
|
||||
"{} {pos}s must be declared prior to {} {pos}s",
|
||||
param_ord,
|
||||
@ -430,6 +437,13 @@ fn validate_generics_order<'a>(
|
||||
}
|
||||
err.emit();
|
||||
}
|
||||
|
||||
// FIXME(const_generics): we shouldn't have to abort here at all, but we currently get ICEs
|
||||
// if we don't. Const parameters and type parameters can currently conflict if they
|
||||
// are out-of-order.
|
||||
if !out_of_order.is_empty() && found_type && found_const {
|
||||
FatalError.raise();
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Visitor<'a> for AstValidator<'a> {
|
||||
|
@ -553,7 +553,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
|
||||
tcx.intern_substs(&substs)
|
||||
}
|
||||
|
||||
/// Given the type/region arguments provided to some path (along with
|
||||
/// Given the type/lifetime/const arguments provided to some path (along with
|
||||
/// an implicit `Self`, if this is a trait reference) returns the complete
|
||||
/// set of substitutions. This may involve applying defaulted type parameters.
|
||||
///
|
||||
@ -678,7 +678,7 @@ 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.types.err.into()
|
||||
tcx.consts.err.into()
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -421,8 +421,8 @@ fn check_where_clauses<'a, 'gcx, 'fcx, 'tcx>(
|
||||
return_ty: Option<Ty<'tcx>>,
|
||||
) {
|
||||
let predicates = fcx.tcx.predicates_of(def_id);
|
||||
|
||||
let generics = tcx.generics_of(def_id);
|
||||
|
||||
let is_our_default = |def: &ty::GenericParamDef| {
|
||||
match def.kind {
|
||||
GenericParamDefKind::Type { has_default, .. } => {
|
||||
@ -465,6 +465,7 @@ fn check_where_clauses<'a, 'gcx, 'fcx, 'tcx>(
|
||||
// All regions are identity.
|
||||
fcx.tcx.mk_param_from_def(param)
|
||||
}
|
||||
|
||||
GenericParamDefKind::Type { .. } => {
|
||||
// If the param has a default,
|
||||
if is_our_default(param) {
|
||||
@ -478,25 +479,24 @@ fn check_where_clauses<'a, 'gcx, 'fcx, 'tcx>(
|
||||
// Mark unwanted params as err.
|
||||
fcx.tcx.types.err.into()
|
||||
}
|
||||
|
||||
GenericParamDefKind::Const => {
|
||||
// FIXME(const_generics:defaults)
|
||||
fcx.tcx.types.err.into()
|
||||
fcx.tcx.consts.err.into()
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Now we build the substituted predicates.
|
||||
let default_obligations = predicates.predicates.iter().flat_map(|&(pred, _)| {
|
||||
#[derive(Default)]
|
||||
struct CountParams { params: FxHashSet<u32> }
|
||||
impl<'tcx> ty::fold::TypeVisitor<'tcx> for CountParams {
|
||||
fn visit_ty(&mut self, t: Ty<'tcx>) -> bool {
|
||||
match t.sty {
|
||||
ty::Param(p) => {
|
||||
self.params.insert(p.idx);
|
||||
t.super_visit_with(self)
|
||||
}
|
||||
_ => t.super_visit_with(self)
|
||||
if let ty::Param(param) = t.sty {
|
||||
self.params.insert(param.idx);
|
||||
}
|
||||
t.super_visit_with(self)
|
||||
}
|
||||
|
||||
fn visit_region(&mut self, _: ty::Region<'tcx>) -> bool {
|
||||
|
@ -1,12 +1,12 @@
|
||||
#![feature(const_generics)]
|
||||
//~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash
|
||||
|
||||
fn foo<const X: (), T>(_: &T) {
|
||||
//~^ ERROR type parameters must be declared prior to const parameters
|
||||
}
|
||||
|
||||
fn bar<const X: (), 'a>(_: &'a ()) {
|
||||
//~^ ERROR lifetime parameters must be declared prior to const parameters
|
||||
}
|
||||
|
||||
fn foo<const X: (), T>(_: &T) {
|
||||
//~^ ERROR type parameters must be declared prior to const parameters
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
@ -4,17 +4,17 @@ warning: the feature `const_generics` is incomplete and may cause the compiler t
|
||||
LL | #![feature(const_generics)]
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
||||
error: type parameters must be declared prior to const parameters
|
||||
--> $DIR/const-param-before-other-params.rs:4:21
|
||||
|
|
||||
LL | fn foo<const X: (), T>(_: &T) {
|
||||
| --------------^- help: reorder the parameters: lifetimes, then types, then consts: `<T, const X: ()>`
|
||||
|
||||
error: lifetime parameters must be declared prior to const parameters
|
||||
--> $DIR/const-param-before-other-params.rs:8:21
|
||||
--> $DIR/const-param-before-other-params.rs:4:21
|
||||
|
|
||||
LL | fn bar<const X: (), 'a>(_: &'a ()) {
|
||||
| --------------^^- help: reorder the parameters: lifetimes, then types, then consts: `<'a, const X: ()>`
|
||||
|
||||
error: type parameters must be declared prior to const parameters
|
||||
--> $DIR/const-param-before-other-params.rs:8:21
|
||||
|
|
||||
LL | fn foo<const X: (), T>(_: &T) {
|
||||
| --------------^- help: reorder the parameters: lifetimes, then types, then consts: `<T, const X: ()>`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
@ -0,0 +1,3 @@
|
||||
trait Trait<const T: ()> {} //~ ERROR const generics are unstable
|
||||
|
||||
fn main() {}
|
@ -0,0 +1,12 @@
|
||||
error[E0658]: const generics are unstable
|
||||
--> $DIR/const-param-in-trait-ungated.rs:1:19
|
||||
|
|
||||
LL | trait Trait<const T: ()> {}
|
||||
| ^
|
||||
|
|
||||
= note: for more information, see https://github.com/rust-lang/rust/issues/44580
|
||||
= help: add #![feature(const_generics)] to the crate attributes to enable
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0658`.
|
8
src/test/ui/const-generics/const-param-in-trait.rs
Normal file
8
src/test/ui/const-generics/const-param-in-trait.rs
Normal file
@ -0,0 +1,8 @@
|
||||
// run-pass
|
||||
|
||||
#![feature(const_generics)]
|
||||
//~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash
|
||||
|
||||
trait Trait<const T: ()> {}
|
||||
|
||||
fn main() {}
|
6
src/test/ui/const-generics/const-param-in-trait.stderr
Normal file
6
src/test/ui/const-generics/const-param-in-trait.stderr
Normal file
@ -0,0 +1,6 @@
|
||||
warning: the feature `const_generics` is incomplete and may cause the compiler to crash
|
||||
--> $DIR/const-param-in-trait.rs:3:12
|
||||
|
|
||||
LL | #![feature(const_generics)]
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
Loading…
Reference in New Issue
Block a user