Avoid a track_errors
by bubbling up most errors from check_well_formed
This commit is contained in:
parent
7849162ace
commit
fd9ef69adf
33 changed files with 337 additions and 305 deletions
|
@ -54,7 +54,7 @@ pub use worker_local::{Registry, WorkerLocal};
|
|||
mod parallel;
|
||||
#[cfg(parallel_compiler)]
|
||||
pub use parallel::scope;
|
||||
pub use parallel::{join, par_for_each_in, par_map, parallel_guard};
|
||||
pub use parallel::{join, par_for_each_in, par_map, parallel_guard, try_par_for_each_in};
|
||||
|
||||
pub use std::sync::atomic::Ordering;
|
||||
pub use std::sync::atomic::Ordering::SeqCst;
|
||||
|
|
|
@ -77,6 +77,15 @@ mod disabled {
|
|||
})
|
||||
}
|
||||
|
||||
pub fn try_par_for_each_in<T: IntoIterator, E: Copy>(
|
||||
t: T,
|
||||
mut for_each: impl FnMut(T::Item) -> Result<(), E>,
|
||||
) -> Result<(), E> {
|
||||
parallel_guard(|guard| {
|
||||
t.into_iter().fold(Ok(()), |ret, i| guard.run(|| for_each(i)).unwrap_or(ret).and(ret))
|
||||
})
|
||||
}
|
||||
|
||||
pub fn par_map<T: IntoIterator, R, C: FromIterator<R>>(
|
||||
t: T,
|
||||
mut map: impl FnMut(<<T as IntoIterator>::IntoIter as Iterator>::Item) -> R,
|
||||
|
@ -167,6 +176,26 @@ mod enabled {
|
|||
});
|
||||
}
|
||||
|
||||
pub fn try_par_for_each_in<
|
||||
T: IntoIterator + IntoParallelIterator<Item = <T as IntoIterator>::Item>,
|
||||
E: Copy + Send,
|
||||
>(
|
||||
t: T,
|
||||
for_each: impl Fn(<T as IntoIterator>::Item) -> Result<(), E> + DynSync + DynSend,
|
||||
) -> Result<(), E> {
|
||||
parallel_guard(|guard| {
|
||||
if mode::is_dyn_thread_safe() {
|
||||
let for_each = FromDyn::from(for_each);
|
||||
t.into_par_iter()
|
||||
.fold_with(Ok(()), |ret, i| guard.run(|| for_each(i)).unwrap_or(ret).and(ret))
|
||||
.reduce(|| Ok(()), |a, b| a.and(b))
|
||||
} else {
|
||||
t.into_iter()
|
||||
.fold(Ok(()), |ret, i| guard.run(|| for_each(i)).unwrap_or(ret).and(ret))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
pub fn par_map<
|
||||
I,
|
||||
T: IntoIterator<Item = I> + IntoParallelIterator<Item = I>,
|
||||
|
|
|
@ -92,7 +92,8 @@ pub(super) fn enter_wf_checking_ctxt<'tcx, F>(
|
|||
span: Span,
|
||||
body_def_id: LocalDefId,
|
||||
f: F,
|
||||
) where
|
||||
) -> Result<(), ErrorGuaranteed>
|
||||
where
|
||||
F: for<'a> FnOnce(&WfCheckingCtxt<'a, 'tcx>),
|
||||
{
|
||||
let param_env = tcx.param_env(body_def_id);
|
||||
|
@ -106,40 +107,46 @@ pub(super) fn enter_wf_checking_ctxt<'tcx, F>(
|
|||
}
|
||||
f(&mut wfcx);
|
||||
|
||||
let assumed_wf_types = match wfcx.ocx.assumed_wf_types_and_report_errors(param_env, body_def_id)
|
||||
{
|
||||
Ok(wf_types) => wf_types,
|
||||
Err(_guar) => return,
|
||||
};
|
||||
let assumed_wf_types = wfcx.ocx.assumed_wf_types_and_report_errors(param_env, body_def_id)?;
|
||||
|
||||
let implied_bounds = infcx.implied_bounds_tys(param_env, body_def_id, assumed_wf_types);
|
||||
|
||||
let errors = wfcx.select_all_or_error();
|
||||
if !errors.is_empty() {
|
||||
infcx.err_ctxt().report_fulfillment_errors(errors);
|
||||
return;
|
||||
let err = infcx.err_ctxt().report_fulfillment_errors(errors);
|
||||
if tcx.sess.err_count() > 0 {
|
||||
return Err(err);
|
||||
} else {
|
||||
// HACK(oli-obk): tests/ui/specialization/min_specialization/specialize_on_type_error.rs causes an
|
||||
// error (delay_span_bug) during normalization, without reporting an error, so we need to act as if
|
||||
// no error happened, in order to let our callers continue and report an error later in
|
||||
// check_impl_items_against_trait.
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
|
||||
let outlives_env = OutlivesEnvironment::with_bounds(param_env, implied_bounds);
|
||||
|
||||
let _ = wfcx.ocx.resolve_regions_and_report_errors(body_def_id, &outlives_env);
|
||||
wfcx.ocx.resolve_regions_and_report_errors(body_def_id, &outlives_env)?;
|
||||
infcx.tainted_by_errors().error_reported()
|
||||
}
|
||||
|
||||
fn check_well_formed(tcx: TyCtxt<'_>, def_id: hir::OwnerId) {
|
||||
fn check_well_formed(tcx: TyCtxt<'_>, def_id: hir::OwnerId) -> Result<(), ErrorGuaranteed> {
|
||||
let node = tcx.hir().owner(def_id);
|
||||
match node {
|
||||
hir::OwnerNode::Crate(_) => {}
|
||||
let mut res = match node {
|
||||
hir::OwnerNode::Crate(_) => bug!("check_well_formed cannot be applied to the crate root"),
|
||||
hir::OwnerNode::Item(item) => check_item(tcx, item),
|
||||
hir::OwnerNode::TraitItem(item) => check_trait_item(tcx, item),
|
||||
hir::OwnerNode::ImplItem(item) => check_impl_item(tcx, item),
|
||||
hir::OwnerNode::ForeignItem(item) => check_foreign_item(tcx, item),
|
||||
}
|
||||
};
|
||||
|
||||
if let Some(generics) = node.generics() {
|
||||
for param in generics.params {
|
||||
check_param_wf(tcx, param)
|
||||
res = res.and(check_param_wf(tcx, param));
|
||||
}
|
||||
}
|
||||
res
|
||||
}
|
||||
|
||||
/// Checks that the field types (in a struct def'n) or argument types (in an enum def'n) are
|
||||
|
@ -156,7 +163,7 @@ fn check_well_formed(tcx: TyCtxt<'_>, def_id: hir::OwnerId) {
|
|||
/// not included it frequently leads to confusing errors in fn bodies. So it's better to check
|
||||
/// the types first.
|
||||
#[instrument(skip(tcx), level = "debug")]
|
||||
fn check_item<'tcx>(tcx: TyCtxt<'tcx>, item: &'tcx hir::Item<'tcx>) {
|
||||
fn check_item<'tcx>(tcx: TyCtxt<'tcx>, item: &'tcx hir::Item<'tcx>) -> Result<(), ErrorGuaranteed> {
|
||||
let def_id = item.owner_id.def_id;
|
||||
|
||||
debug!(
|
||||
|
@ -186,31 +193,32 @@ fn check_item<'tcx>(tcx: TyCtxt<'tcx>, item: &'tcx hir::Item<'tcx>) {
|
|||
let is_auto = tcx
|
||||
.impl_trait_ref(def_id)
|
||||
.is_some_and(|trait_ref| tcx.trait_is_auto(trait_ref.skip_binder().def_id));
|
||||
let mut res = Ok(());
|
||||
if let (hir::Defaultness::Default { .. }, true) = (impl_.defaultness, is_auto) {
|
||||
let sp = impl_.of_trait.as_ref().map_or(item.span, |t| t.path.span);
|
||||
let mut err =
|
||||
tcx.sess.struct_span_err(sp, "impls of auto traits cannot be default");
|
||||
err.span_labels(impl_.defaultness_span, "default because of this");
|
||||
err.span_label(sp, "auto trait");
|
||||
err.emit();
|
||||
res = Err(err.emit());
|
||||
}
|
||||
// We match on both `ty::ImplPolarity` and `ast::ImplPolarity` just to get the `!` span.
|
||||
match (tcx.impl_polarity(def_id), impl_.polarity) {
|
||||
(ty::ImplPolarity::Positive, _) => {
|
||||
check_impl(tcx, item, impl_.self_ty, &impl_.of_trait);
|
||||
res = res.and(check_impl(tcx, item, impl_.self_ty, &impl_.of_trait));
|
||||
}
|
||||
(ty::ImplPolarity::Negative, ast::ImplPolarity::Negative(span)) => {
|
||||
// FIXME(#27579): what amount of WF checking do we need for neg impls?
|
||||
if let hir::Defaultness::Default { .. } = impl_.defaultness {
|
||||
let mut spans = vec![span];
|
||||
spans.extend(impl_.defaultness_span);
|
||||
struct_span_err!(
|
||||
res = Err(struct_span_err!(
|
||||
tcx.sess,
|
||||
spans,
|
||||
E0750,
|
||||
"negative impls cannot be default impls"
|
||||
)
|
||||
.emit();
|
||||
.emit());
|
||||
}
|
||||
}
|
||||
(ty::ImplPolarity::Reservation, _) => {
|
||||
|
@ -218,49 +226,52 @@ fn check_item<'tcx>(tcx: TyCtxt<'tcx>, item: &'tcx hir::Item<'tcx>) {
|
|||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
res
|
||||
}
|
||||
hir::ItemKind::Fn(ref sig, ..) => {
|
||||
check_item_fn(tcx, def_id, item.ident, item.span, sig.decl);
|
||||
check_item_fn(tcx, def_id, item.ident, item.span, sig.decl)
|
||||
}
|
||||
hir::ItemKind::Static(ty, ..) => {
|
||||
check_item_type(tcx, def_id, ty.span, UnsizedHandling::Forbid);
|
||||
check_item_type(tcx, def_id, ty.span, UnsizedHandling::Forbid)
|
||||
}
|
||||
hir::ItemKind::Const(ty, ..) => {
|
||||
check_item_type(tcx, def_id, ty.span, UnsizedHandling::Forbid);
|
||||
check_item_type(tcx, def_id, ty.span, UnsizedHandling::Forbid)
|
||||
}
|
||||
hir::ItemKind::Struct(_, ast_generics) => {
|
||||
check_type_defn(tcx, item, false);
|
||||
let res = check_type_defn(tcx, item, false);
|
||||
check_variances_for_type_defn(tcx, item, ast_generics);
|
||||
res
|
||||
}
|
||||
hir::ItemKind::Union(_, ast_generics) => {
|
||||
check_type_defn(tcx, item, true);
|
||||
let res = check_type_defn(tcx, item, true);
|
||||
check_variances_for_type_defn(tcx, item, ast_generics);
|
||||
res
|
||||
}
|
||||
hir::ItemKind::Enum(_, ast_generics) => {
|
||||
check_type_defn(tcx, item, true);
|
||||
let res = check_type_defn(tcx, item, true);
|
||||
check_variances_for_type_defn(tcx, item, ast_generics);
|
||||
res
|
||||
}
|
||||
hir::ItemKind::Trait(..) => {
|
||||
check_trait(tcx, item);
|
||||
}
|
||||
hir::ItemKind::TraitAlias(..) => {
|
||||
check_trait(tcx, item);
|
||||
}
|
||||
hir::ItemKind::Trait(..) => check_trait(tcx, item),
|
||||
hir::ItemKind::TraitAlias(..) => check_trait(tcx, item),
|
||||
// `ForeignItem`s are handled separately.
|
||||
hir::ItemKind::ForeignMod { .. } => {}
|
||||
hir::ItemKind::ForeignMod { .. } => Ok(()),
|
||||
hir::ItemKind::TyAlias(hir_ty, ast_generics) => {
|
||||
if tcx.type_alias_is_lazy(item.owner_id) {
|
||||
// Bounds of lazy type aliases and of eager ones that contain opaque types are respected.
|
||||
// E.g: `type X = impl Trait;`, `type X = (impl Trait, Y);`.
|
||||
check_item_type(tcx, def_id, hir_ty.span, UnsizedHandling::Allow);
|
||||
let res = check_item_type(tcx, def_id, hir_ty.span, UnsizedHandling::Allow);
|
||||
check_variances_for_type_defn(tcx, item, ast_generics);
|
||||
res
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
_ => Ok(()),
|
||||
}
|
||||
}
|
||||
|
||||
fn check_foreign_item(tcx: TyCtxt<'_>, item: &hir::ForeignItem<'_>) {
|
||||
fn check_foreign_item(tcx: TyCtxt<'_>, item: &hir::ForeignItem<'_>) -> Result<(), ErrorGuaranteed> {
|
||||
let def_id = item.owner_id.def_id;
|
||||
|
||||
debug!(
|
||||
|
@ -275,11 +286,14 @@ fn check_foreign_item(tcx: TyCtxt<'_>, item: &hir::ForeignItem<'_>) {
|
|||
hir::ForeignItemKind::Static(ty, ..) => {
|
||||
check_item_type(tcx, def_id, ty.span, UnsizedHandling::AllowIfForeignTail)
|
||||
}
|
||||
hir::ForeignItemKind::Type => (),
|
||||
hir::ForeignItemKind::Type => Ok(()),
|
||||
}
|
||||
}
|
||||
|
||||
fn check_trait_item(tcx: TyCtxt<'_>, trait_item: &hir::TraitItem<'_>) {
|
||||
fn check_trait_item(
|
||||
tcx: TyCtxt<'_>,
|
||||
trait_item: &hir::TraitItem<'_>,
|
||||
) -> Result<(), ErrorGuaranteed> {
|
||||
let def_id = trait_item.owner_id.def_id;
|
||||
|
||||
let (method_sig, span) = match trait_item.kind {
|
||||
|
@ -288,18 +302,19 @@ fn check_trait_item(tcx: TyCtxt<'_>, trait_item: &hir::TraitItem<'_>) {
|
|||
_ => (None, trait_item.span),
|
||||
};
|
||||
check_object_unsafe_self_trait_by_name(tcx, trait_item);
|
||||
check_associated_item(tcx, def_id, span, method_sig);
|
||||
let mut res = check_associated_item(tcx, def_id, span, method_sig);
|
||||
|
||||
if matches!(trait_item.kind, hir::TraitItemKind::Fn(..)) {
|
||||
for &assoc_ty_def_id in tcx.associated_types_for_impl_traits_in_associated_fn(def_id) {
|
||||
check_associated_item(
|
||||
res = res.and(check_associated_item(
|
||||
tcx,
|
||||
assoc_ty_def_id.expect_local(),
|
||||
tcx.def_span(assoc_ty_def_id),
|
||||
None,
|
||||
);
|
||||
));
|
||||
}
|
||||
}
|
||||
res
|
||||
}
|
||||
|
||||
/// Require that the user writes where clauses on GATs for the implicit
|
||||
|
@ -826,7 +841,7 @@ fn check_object_unsafe_self_trait_by_name(tcx: TyCtxt<'_>, item: &hir::TraitItem
|
|||
}
|
||||
}
|
||||
|
||||
fn check_impl_item(tcx: TyCtxt<'_>, impl_item: &hir::ImplItem<'_>) {
|
||||
fn check_impl_item(tcx: TyCtxt<'_>, impl_item: &hir::ImplItem<'_>) -> Result<(), ErrorGuaranteed> {
|
||||
let (method_sig, span) = match impl_item.kind {
|
||||
hir::ImplItemKind::Fn(ref sig, _) => (Some(sig), impl_item.span),
|
||||
// Constrain binding and overflow error spans to `<Ty>` in `type foo = <Ty>`.
|
||||
|
@ -834,13 +849,13 @@ fn check_impl_item(tcx: TyCtxt<'_>, impl_item: &hir::ImplItem<'_>) {
|
|||
_ => (None, impl_item.span),
|
||||
};
|
||||
|
||||
check_associated_item(tcx, impl_item.owner_id.def_id, span, method_sig);
|
||||
check_associated_item(tcx, impl_item.owner_id.def_id, span, method_sig)
|
||||
}
|
||||
|
||||
fn check_param_wf(tcx: TyCtxt<'_>, param: &hir::GenericParam<'_>) {
|
||||
fn check_param_wf(tcx: TyCtxt<'_>, param: &hir::GenericParam<'_>) -> Result<(), ErrorGuaranteed> {
|
||||
match param.kind {
|
||||
// We currently only check wf of const params here.
|
||||
hir::GenericParamKind::Lifetime { .. } | hir::GenericParamKind::Type { .. } => (),
|
||||
hir::GenericParamKind::Lifetime { .. } | hir::GenericParamKind::Type { .. } => Ok(()),
|
||||
|
||||
// Const parameters are well formed if their type is structural match.
|
||||
hir::GenericParamKind::Const { ty: hir_ty, default: _ } => {
|
||||
|
@ -860,68 +875,66 @@ fn check_param_wf(tcx: TyCtxt<'_>, param: &hir::GenericParam<'_>) {
|
|||
ty,
|
||||
trait_def_id,
|
||||
);
|
||||
});
|
||||
})
|
||||
} else {
|
||||
let diag = match ty.kind() {
|
||||
ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) | ty::Error(_) => None,
|
||||
ty::FnPtr(_) => Some(tcx.sess.struct_span_err(
|
||||
let mut diag = match ty.kind() {
|
||||
ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) | ty::Error(_) => return Ok(()),
|
||||
ty::FnPtr(_) => tcx.sess.struct_span_err(
|
||||
hir_ty.span,
|
||||
"using function pointers as const generic parameters is forbidden",
|
||||
)),
|
||||
ty::RawPtr(_) => Some(tcx.sess.struct_span_err(
|
||||
),
|
||||
ty::RawPtr(_) => tcx.sess.struct_span_err(
|
||||
hir_ty.span,
|
||||
"using raw pointers as const generic parameters is forbidden",
|
||||
)),
|
||||
_ => Some(tcx.sess.struct_span_err(
|
||||
),
|
||||
_ => tcx.sess.struct_span_err(
|
||||
hir_ty.span,
|
||||
format!("`{}` is forbidden as the type of a const generic parameter", ty),
|
||||
)),
|
||||
),
|
||||
};
|
||||
|
||||
if let Some(mut diag) = diag {
|
||||
diag.note("the only supported types are integers, `bool` and `char`");
|
||||
diag.note("the only supported types are integers, `bool` and `char`");
|
||||
|
||||
let cause = ObligationCause::misc(hir_ty.span, param.def_id);
|
||||
let may_suggest_feature = match type_allowed_to_implement_const_param_ty(
|
||||
tcx,
|
||||
tcx.param_env(param.def_id),
|
||||
ty,
|
||||
cause,
|
||||
) {
|
||||
// Can never implement `ConstParamTy`, don't suggest anything.
|
||||
Err(ConstParamTyImplementationError::NotAnAdtOrBuiltinAllowed) => false,
|
||||
// May be able to implement `ConstParamTy`. Only emit the feature help
|
||||
// if the type is local, since the user may be able to fix the local type.
|
||||
Err(ConstParamTyImplementationError::InfrigingFields(..)) => {
|
||||
fn ty_is_local(ty: Ty<'_>) -> bool {
|
||||
match ty.kind() {
|
||||
ty::Adt(adt_def, ..) => adt_def.did().is_local(),
|
||||
// Arrays and slices use the inner type's `ConstParamTy`.
|
||||
ty::Array(ty, ..) => ty_is_local(*ty),
|
||||
ty::Slice(ty) => ty_is_local(*ty),
|
||||
// `&` references use the inner type's `ConstParamTy`.
|
||||
// `&mut` are not supported.
|
||||
ty::Ref(_, ty, ast::Mutability::Not) => ty_is_local(*ty),
|
||||
// Say that a tuple is local if any of its components are local.
|
||||
// This is not strictly correct, but it's likely that the user can fix the local component.
|
||||
ty::Tuple(tys) => tys.iter().any(|ty| ty_is_local(ty)),
|
||||
_ => false,
|
||||
}
|
||||
let cause = ObligationCause::misc(hir_ty.span, param.def_id);
|
||||
let may_suggest_feature = match type_allowed_to_implement_const_param_ty(
|
||||
tcx,
|
||||
tcx.param_env(param.def_id),
|
||||
ty,
|
||||
cause,
|
||||
) {
|
||||
// Can never implement `ConstParamTy`, don't suggest anything.
|
||||
Err(ConstParamTyImplementationError::NotAnAdtOrBuiltinAllowed) => false,
|
||||
// May be able to implement `ConstParamTy`. Only emit the feature help
|
||||
// if the type is local, since the user may be able to fix the local type.
|
||||
Err(ConstParamTyImplementationError::InfrigingFields(..)) => {
|
||||
fn ty_is_local(ty: Ty<'_>) -> bool {
|
||||
match ty.kind() {
|
||||
ty::Adt(adt_def, ..) => adt_def.did().is_local(),
|
||||
// Arrays and slices use the inner type's `ConstParamTy`.
|
||||
ty::Array(ty, ..) => ty_is_local(*ty),
|
||||
ty::Slice(ty) => ty_is_local(*ty),
|
||||
// `&` references use the inner type's `ConstParamTy`.
|
||||
// `&mut` are not supported.
|
||||
ty::Ref(_, ty, ast::Mutability::Not) => ty_is_local(*ty),
|
||||
// Say that a tuple is local if any of its components are local.
|
||||
// This is not strictly correct, but it's likely that the user can fix the local component.
|
||||
ty::Tuple(tys) => tys.iter().any(|ty| ty_is_local(ty)),
|
||||
_ => false,
|
||||
}
|
||||
|
||||
ty_is_local(ty)
|
||||
}
|
||||
// Implments `ConstParamTy`, suggest adding the feature to enable.
|
||||
Ok(..) => true,
|
||||
};
|
||||
if may_suggest_feature && tcx.sess.is_nightly_build() {
|
||||
diag.help(
|
||||
|
||||
ty_is_local(ty)
|
||||
}
|
||||
// Implments `ConstParamTy`, suggest adding the feature to enable.
|
||||
Ok(..) => true,
|
||||
};
|
||||
if may_suggest_feature && tcx.sess.is_nightly_build() {
|
||||
diag.help(
|
||||
"add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types",
|
||||
);
|
||||
}
|
||||
|
||||
diag.emit();
|
||||
}
|
||||
|
||||
Err(diag.emit())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -933,7 +946,7 @@ fn check_associated_item(
|
|||
item_id: LocalDefId,
|
||||
span: Span,
|
||||
sig_if_method: Option<&hir::FnSig<'_>>,
|
||||
) {
|
||||
) -> Result<(), ErrorGuaranteed> {
|
||||
let loc = Some(WellFormedLoc::Ty(item_id));
|
||||
enter_wf_checking_ctxt(tcx, span, item_id, |wfcx| {
|
||||
let item = tcx.associated_item(item_id);
|
||||
|
@ -985,7 +998,11 @@ fn item_adt_kind(kind: &ItemKind<'_>) -> Option<AdtKind> {
|
|||
}
|
||||
|
||||
/// In a type definition, we check that to ensure that the types of the fields are well-formed.
|
||||
fn check_type_defn<'tcx>(tcx: TyCtxt<'tcx>, item: &hir::Item<'tcx>, all_sized: bool) {
|
||||
fn check_type_defn<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
item: &hir::Item<'tcx>,
|
||||
all_sized: bool,
|
||||
) -> Result<(), ErrorGuaranteed> {
|
||||
let _ = tcx.representability(item.owner_id.def_id);
|
||||
let adt_def = tcx.adt_def(item.owner_id);
|
||||
|
||||
|
@ -1080,11 +1097,11 @@ fn check_type_defn<'tcx>(tcx: TyCtxt<'tcx>, item: &hir::Item<'tcx>, all_sized: b
|
|||
}
|
||||
|
||||
check_where_clauses(wfcx, item.span, item.owner_id.def_id);
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
#[instrument(skip(tcx, item))]
|
||||
fn check_trait(tcx: TyCtxt<'_>, item: &hir::Item<'_>) {
|
||||
fn check_trait(tcx: TyCtxt<'_>, item: &hir::Item<'_>) -> Result<(), ErrorGuaranteed> {
|
||||
debug!(?item.owner_id);
|
||||
|
||||
let def_id = item.owner_id.def_id;
|
||||
|
@ -1103,7 +1120,7 @@ fn check_trait(tcx: TyCtxt<'_>, item: &hir::Item<'_>) {
|
|||
}
|
||||
}
|
||||
|
||||
enter_wf_checking_ctxt(tcx, item.span, def_id, |wfcx| {
|
||||
let res = enter_wf_checking_ctxt(tcx, item.span, def_id, |wfcx| {
|
||||
check_where_clauses(wfcx, item.span, def_id)
|
||||
});
|
||||
|
||||
|
@ -1111,6 +1128,7 @@ fn check_trait(tcx: TyCtxt<'_>, item: &hir::Item<'_>) {
|
|||
if let hir::ItemKind::Trait(..) = item.kind {
|
||||
check_gat_where_clauses(tcx, item.owner_id.def_id);
|
||||
}
|
||||
res
|
||||
}
|
||||
|
||||
/// Checks all associated type defaults of trait `trait_def_id`.
|
||||
|
@ -1142,7 +1160,7 @@ fn check_item_fn(
|
|||
ident: Ident,
|
||||
span: Span,
|
||||
decl: &hir::FnDecl<'_>,
|
||||
) {
|
||||
) -> Result<(), ErrorGuaranteed> {
|
||||
enter_wf_checking_ctxt(tcx, span, def_id, |wfcx| {
|
||||
let sig = tcx.fn_sig(def_id).instantiate_identity();
|
||||
check_fn_or_method(wfcx, ident.span, sig, decl, def_id);
|
||||
|
@ -1160,7 +1178,7 @@ fn check_item_type(
|
|||
item_id: LocalDefId,
|
||||
ty_span: Span,
|
||||
unsized_handling: UnsizedHandling,
|
||||
) {
|
||||
) -> Result<(), ErrorGuaranteed> {
|
||||
debug!("check_item_type: {:?}", item_id);
|
||||
|
||||
enter_wf_checking_ctxt(tcx, ty_span, item_id, |wfcx| {
|
||||
|
@ -1200,7 +1218,7 @@ fn check_item_type(
|
|||
tcx.require_lang_item(LangItem::Sync, Some(ty_span)),
|
||||
);
|
||||
}
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
#[instrument(level = "debug", skip(tcx, ast_self_ty, ast_trait_ref))]
|
||||
|
@ -1209,7 +1227,7 @@ fn check_impl<'tcx>(
|
|||
item: &'tcx hir::Item<'tcx>,
|
||||
ast_self_ty: &hir::Ty<'_>,
|
||||
ast_trait_ref: &Option<hir::TraitRef<'_>>,
|
||||
) {
|
||||
) -> Result<(), ErrorGuaranteed> {
|
||||
enter_wf_checking_ctxt(tcx, item.span, item.owner_id.def_id, |wfcx| {
|
||||
match ast_trait_ref {
|
||||
Some(ast_trait_ref) => {
|
||||
|
@ -1258,7 +1276,7 @@ fn check_impl<'tcx>(
|
|||
}
|
||||
|
||||
check_where_clauses(wfcx, item.span, item.owner_id.def_id);
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
/// Checks where-clauses and inline bounds that are declared on `def_id`.
|
||||
|
@ -1879,12 +1897,12 @@ impl<'tcx> WfCheckingCtxt<'_, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
fn check_mod_type_wf(tcx: TyCtxt<'_>, module: LocalModDefId) {
|
||||
fn check_mod_type_wf(tcx: TyCtxt<'_>, module: LocalModDefId) -> Result<(), ErrorGuaranteed> {
|
||||
let items = tcx.hir_module_items(module);
|
||||
items.par_items(|item| tcx.ensure().check_well_formed(item.owner_id));
|
||||
items.par_impl_items(|item| tcx.ensure().check_well_formed(item.owner_id));
|
||||
items.par_trait_items(|item| tcx.ensure().check_well_formed(item.owner_id));
|
||||
items.par_foreign_items(|item| tcx.ensure().check_well_formed(item.owner_id));
|
||||
let mut res = items.par_items(|item| tcx.check_well_formed(item.owner_id));
|
||||
res = res.and(items.par_impl_items(|item| tcx.check_well_formed(item.owner_id)));
|
||||
res = res.and(items.par_trait_items(|item| tcx.check_well_formed(item.owner_id)));
|
||||
res.and(items.par_foreign_items(|item| tcx.check_well_formed(item.owner_id)))
|
||||
}
|
||||
|
||||
fn error_392(
|
||||
|
|
|
@ -205,10 +205,8 @@ pub fn check_crate(tcx: TyCtxt<'_>) -> Result<(), ErrorGuaranteed> {
|
|||
})?;
|
||||
}
|
||||
|
||||
tcx.sess.track_errors(|| {
|
||||
tcx.sess.time("wf_checking", || {
|
||||
tcx.hir().par_for_each_module(|module| tcx.ensure().check_mod_type_wf(module))
|
||||
});
|
||||
tcx.sess.time("wf_checking", || {
|
||||
tcx.hir().try_par_for_each_module(|module| tcx.check_mod_type_wf(module))
|
||||
})?;
|
||||
|
||||
// NOTE: This is copy/pasted in librustdoc/core.rs and should be kept in sync.
|
||||
|
|
|
@ -6,7 +6,7 @@ use rustc_ast as ast;
|
|||
use rustc_data_structures::fingerprint::Fingerprint;
|
||||
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
|
||||
use rustc_data_structures::svh::Svh;
|
||||
use rustc_data_structures::sync::{par_for_each_in, DynSend, DynSync};
|
||||
use rustc_data_structures::sync::{par_for_each_in, try_par_for_each_in, DynSend, DynSync};
|
||||
use rustc_hir::def::{DefKind, Res};
|
||||
use rustc_hir::def_id::{DefId, LocalDefId, LocalModDefId, LOCAL_CRATE};
|
||||
use rustc_hir::definitions::{DefKey, DefPath, DefPathData, DefPathHash};
|
||||
|
@ -16,7 +16,7 @@ use rustc_index::Idx;
|
|||
use rustc_middle::hir::nested_filter;
|
||||
use rustc_span::def_id::StableCrateId;
|
||||
use rustc_span::symbol::{kw, sym, Ident, Symbol};
|
||||
use rustc_span::Span;
|
||||
use rustc_span::{ErrorGuaranteed, Span};
|
||||
use rustc_target::spec::abi::Abi;
|
||||
|
||||
#[inline]
|
||||
|
@ -632,6 +632,17 @@ impl<'hir> Map<'hir> {
|
|||
})
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn try_par_for_each_module(
|
||||
self,
|
||||
f: impl Fn(LocalModDefId) -> Result<(), ErrorGuaranteed> + DynSend + DynSync,
|
||||
) -> Result<(), ErrorGuaranteed> {
|
||||
let crate_items = self.tcx.hir_crate_items(());
|
||||
try_par_for_each_in(&crate_items.submodules[..], |module| {
|
||||
f(LocalModDefId::new_unchecked(module.def_id))
|
||||
})
|
||||
}
|
||||
|
||||
/// Returns an iterator for the nodes in the ancestor tree of the `current_id`
|
||||
/// until the crate root is reached. Prefer this over your own loop using `parent_id`.
|
||||
#[inline]
|
||||
|
|
|
@ -9,12 +9,12 @@ pub mod place;
|
|||
use crate::query::Providers;
|
||||
use crate::ty::{EarlyBinder, ImplSubject, TyCtxt};
|
||||
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
|
||||
use rustc_data_structures::sync::{par_for_each_in, DynSend, DynSync};
|
||||
use rustc_data_structures::sync::{try_par_for_each_in, DynSend, DynSync};
|
||||
use rustc_hir::def::DefKind;
|
||||
use rustc_hir::def_id::{DefId, LocalDefId, LocalModDefId};
|
||||
use rustc_hir::*;
|
||||
use rustc_query_system::ich::StableHashingContext;
|
||||
use rustc_span::{ExpnId, DUMMY_SP};
|
||||
use rustc_span::{ErrorGuaranteed, ExpnId, DUMMY_SP};
|
||||
|
||||
/// Top-level HIR node for current owner. This only contains the node for which
|
||||
/// `HirId::local_id == 0`, and excludes bodies.
|
||||
|
@ -78,20 +78,32 @@ impl ModuleItems {
|
|||
self.owners().map(|id| id.def_id)
|
||||
}
|
||||
|
||||
pub fn par_items(&self, f: impl Fn(ItemId) + DynSend + DynSync) {
|
||||
par_for_each_in(&self.items[..], |&id| f(id))
|
||||
pub fn par_items(
|
||||
&self,
|
||||
f: impl Fn(ItemId) -> Result<(), ErrorGuaranteed> + DynSend + DynSync,
|
||||
) -> Result<(), ErrorGuaranteed> {
|
||||
try_par_for_each_in(&self.items[..], |&id| f(id))
|
||||
}
|
||||
|
||||
pub fn par_trait_items(&self, f: impl Fn(TraitItemId) + DynSend + DynSync) {
|
||||
par_for_each_in(&self.trait_items[..], |&id| f(id))
|
||||
pub fn par_trait_items(
|
||||
&self,
|
||||
f: impl Fn(TraitItemId) -> Result<(), ErrorGuaranteed> + DynSend + DynSync,
|
||||
) -> Result<(), ErrorGuaranteed> {
|
||||
try_par_for_each_in(&self.trait_items[..], |&id| f(id))
|
||||
}
|
||||
|
||||
pub fn par_impl_items(&self, f: impl Fn(ImplItemId) + DynSend + DynSync) {
|
||||
par_for_each_in(&self.impl_items[..], |&id| f(id))
|
||||
pub fn par_impl_items(
|
||||
&self,
|
||||
f: impl Fn(ImplItemId) -> Result<(), ErrorGuaranteed> + DynSend + DynSync,
|
||||
) -> Result<(), ErrorGuaranteed> {
|
||||
try_par_for_each_in(&self.impl_items[..], |&id| f(id))
|
||||
}
|
||||
|
||||
pub fn par_foreign_items(&self, f: impl Fn(ForeignItemId) + DynSend + DynSync) {
|
||||
par_for_each_in(&self.foreign_items[..], |&id| f(id))
|
||||
pub fn par_foreign_items(
|
||||
&self,
|
||||
f: impl Fn(ForeignItemId) -> Result<(), ErrorGuaranteed> + DynSend + DynSync,
|
||||
) -> Result<(), ErrorGuaranteed> {
|
||||
try_par_for_each_in(&self.foreign_items[..], |&id| f(id))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -965,7 +965,7 @@ rustc_queries! {
|
|||
desc { |tcx| "checking that impls are well-formed in {}", describe_as_module(key, tcx) }
|
||||
}
|
||||
|
||||
query check_mod_type_wf(key: LocalModDefId) -> () {
|
||||
query check_mod_type_wf(key: LocalModDefId) -> Result<(), ErrorGuaranteed> {
|
||||
desc { |tcx| "checking that types are well-formed in {}", describe_as_module(key, tcx) }
|
||||
}
|
||||
|
||||
|
@ -1499,7 +1499,7 @@ rustc_queries! {
|
|||
feedable
|
||||
}
|
||||
|
||||
query check_well_formed(key: hir::OwnerId) -> () {
|
||||
query check_well_formed(key: hir::OwnerId) -> Result<(), ErrorGuaranteed> {
|
||||
desc { |tcx| "checking that `{}` is well-formed", tcx.def_path_str(key) }
|
||||
}
|
||||
|
||||
|
|
|
@ -24,16 +24,6 @@ help: you might be missing a type parameter
|
|||
LL | impl<N, M, VAL> TypeVal<usize> for Multiply<N, M> where N: TypeVal<VAL> {}
|
||||
| +++++
|
||||
|
||||
error[E0046]: not all trait items implemented, missing: `VAL`
|
||||
--> $DIR/ice-6252.rs:11:1
|
||||
|
|
||||
LL | const VAL: T;
|
||||
| ------------ `VAL` from trait
|
||||
...
|
||||
LL | impl<N, M> TypeVal<usize> for Multiply<N, M> where N: TypeVal<VAL> {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `VAL` in implementation
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0046, E0412.
|
||||
For more information about an error, try `rustc --explain E0046`.
|
||||
For more information about this error, try `rustc --explain E0412`.
|
||||
|
|
|
@ -9,13 +9,10 @@ impl TraitWAssocConst for impl Demo { //~ ERROR E0404
|
|||
}
|
||||
|
||||
fn foo<A: TraitWAssocConst<A=32>>() { //~ ERROR E0658
|
||||
foo::<Demo>()(); //~ ERROR E0271
|
||||
//~^ ERROR E0618
|
||||
//~| ERROR E0277
|
||||
foo::<Demo>()();
|
||||
}
|
||||
|
||||
fn main<A: TraitWAssocConst<A=32>>() { //~ ERROR E0131
|
||||
fn main<A: TraitWAssocConst<A=32>>() {
|
||||
//~^ ERROR E0658
|
||||
foo::<Demo>(); //~ ERROR E0277
|
||||
//~^ ERROR E0271
|
||||
foo::<Demo>();
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@ LL | fn foo<A: TraitWAssocConst<A=32>>() {
|
|||
= help: add `#![feature(associated_const_equality)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: associated const equality is incomplete
|
||||
--> $DIR/issue-105330.rs:17:29
|
||||
--> $DIR/issue-105330.rs:15:29
|
||||
|
|
||||
LL | fn main<A: TraitWAssocConst<A=32>>() {
|
||||
| ^^^^
|
||||
|
@ -39,85 +39,7 @@ error[E0562]: `impl Trait` only allowed in function and inherent method argument
|
|||
LL | impl TraitWAssocConst for impl Demo {
|
||||
| ^^^^^^^^^
|
||||
|
||||
error[E0131]: `main` function is not allowed to have generic parameters
|
||||
--> $DIR/issue-105330.rs:17:8
|
||||
|
|
||||
LL | fn main<A: TraitWAssocConst<A=32>>() {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `main` cannot have generic parameters
|
||||
error: aborting due to 5 previous errors
|
||||
|
||||
error[E0277]: the trait bound `Demo: TraitWAssocConst` is not satisfied
|
||||
--> $DIR/issue-105330.rs:12:11
|
||||
|
|
||||
LL | foo::<Demo>()();
|
||||
| ^^^^ the trait `TraitWAssocConst` is not implemented for `Demo`
|
||||
|
|
||||
help: this trait has no implementations, consider adding one
|
||||
--> $DIR/issue-105330.rs:1:1
|
||||
|
|
||||
LL | pub trait TraitWAssocConst {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
note: required by a bound in `foo`
|
||||
--> $DIR/issue-105330.rs:11:11
|
||||
|
|
||||
LL | fn foo<A: TraitWAssocConst<A=32>>() {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `foo`
|
||||
|
||||
error[E0271]: type mismatch resolving `<Demo as TraitWAssocConst>::A == 32`
|
||||
--> $DIR/issue-105330.rs:12:11
|
||||
|
|
||||
LL | foo::<Demo>()();
|
||||
| ^^^^ expected `32`, found `<Demo as TraitWAssocConst>::A`
|
||||
|
|
||||
= note: expected constant `32`
|
||||
found constant `<Demo as TraitWAssocConst>::A`
|
||||
note: required by a bound in `foo`
|
||||
--> $DIR/issue-105330.rs:11:28
|
||||
|
|
||||
LL | fn foo<A: TraitWAssocConst<A=32>>() {
|
||||
| ^^^^ required by this bound in `foo`
|
||||
|
||||
error[E0618]: expected function, found `()`
|
||||
--> $DIR/issue-105330.rs:12:5
|
||||
|
|
||||
LL | fn foo<A: TraitWAssocConst<A=32>>() {
|
||||
| ----------------------------------- `foo::<Demo>` defined here returns `()`
|
||||
LL | foo::<Demo>()();
|
||||
| ^^^^^^^^^^^^^--
|
||||
| |
|
||||
| call expression requires function
|
||||
|
||||
error[E0277]: the trait bound `Demo: TraitWAssocConst` is not satisfied
|
||||
--> $DIR/issue-105330.rs:19:11
|
||||
|
|
||||
LL | foo::<Demo>();
|
||||
| ^^^^ the trait `TraitWAssocConst` is not implemented for `Demo`
|
||||
|
|
||||
help: this trait has no implementations, consider adding one
|
||||
--> $DIR/issue-105330.rs:1:1
|
||||
|
|
||||
LL | pub trait TraitWAssocConst {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
note: required by a bound in `foo`
|
||||
--> $DIR/issue-105330.rs:11:11
|
||||
|
|
||||
LL | fn foo<A: TraitWAssocConst<A=32>>() {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `foo`
|
||||
|
||||
error[E0271]: type mismatch resolving `<Demo as TraitWAssocConst>::A == 32`
|
||||
--> $DIR/issue-105330.rs:19:11
|
||||
|
|
||||
LL | foo::<Demo>();
|
||||
| ^^^^ expected `32`, found `<Demo as TraitWAssocConst>::A`
|
||||
|
|
||||
= note: expected constant `32`
|
||||
found constant `<Demo as TraitWAssocConst>::A`
|
||||
note: required by a bound in `foo`
|
||||
--> $DIR/issue-105330.rs:11:28
|
||||
|
|
||||
LL | fn foo<A: TraitWAssocConst<A=32>>() {
|
||||
| ^^^^ required by this bound in `foo`
|
||||
|
||||
error: aborting due to 11 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0131, E0271, E0277, E0404, E0562, E0618, E0658.
|
||||
For more information about an error, try `rustc --explain E0131`.
|
||||
Some errors have detailed explanations: E0404, E0562, E0658.
|
||||
For more information about an error, try `rustc --explain E0404`.
|
||||
|
|
|
@ -11,6 +11,7 @@ impl Bar<[u8]> {
|
|||
const SIZE: usize = 32;
|
||||
|
||||
fn new(slice: &[u8; Self::SIZE]) -> Self {
|
||||
//~^ ERROR: the size for values of type `[u8]` cannot be known at compilation time
|
||||
Foo(Box::new(*slice))
|
||||
//~^ ERROR: expected function, tuple struct or tuple variant, found trait `Foo`
|
||||
}
|
||||
|
|
|
@ -7,13 +7,27 @@ LL |
|
|||
LL | fn new(slice: &[u8; Foo::SIZE]) -> Self;
|
||||
| ^^^^^^^^^ cannot refer to the associated constant of trait
|
||||
|
||||
error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
|
||||
--> $DIR/issue-58022.rs:13:41
|
||||
|
|
||||
LL | fn new(slice: &[u8; Self::SIZE]) -> Self {
|
||||
| ^^^^ doesn't have a size known at compile-time
|
||||
|
|
||||
= help: within `Bar<[u8]>`, the trait `Sized` is not implemented for `[u8]`
|
||||
note: required because it appears within the type `Bar<[u8]>`
|
||||
--> $DIR/issue-58022.rs:8:12
|
||||
|
|
||||
LL | pub struct Bar<T: ?Sized>(T);
|
||||
| ^^^
|
||||
= note: the return type of a function must have a statically known size
|
||||
|
||||
error[E0423]: expected function, tuple struct or tuple variant, found trait `Foo`
|
||||
--> $DIR/issue-58022.rs:14:9
|
||||
--> $DIR/issue-58022.rs:15:9
|
||||
|
|
||||
LL | Foo(Box::new(*slice))
|
||||
| ^^^ not a function, tuple struct or tuple variant
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0423, E0790.
|
||||
For more information about an error, try `rustc --explain E0423`.
|
||||
Some errors have detailed explanations: E0277, E0423, E0790.
|
||||
For more information about an error, try `rustc --explain E0277`.
|
||||
|
|
|
@ -6,7 +6,7 @@ trait Test<T> {
|
|||
|
||||
async fn f() {
|
||||
let x = Some(2);
|
||||
if x.is_some() {
|
||||
if x.is_some() { //~ ERROR mismatched types
|
||||
println!("Some");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,6 +7,13 @@ LL | fn is_some(self: T);
|
|||
= note: type of `self` must be `Self` or a type that dereferences to it
|
||||
= help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
|
||||
|
||||
error: aborting due to previous error
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/issue-66312.rs:9:8
|
||||
|
|
||||
LL | if x.is_some() {
|
||||
| ^^^^^^^^^^^ expected `bool`, found `()`
|
||||
|
||||
For more information about this error, try `rustc --explain E0307`.
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0307, E0308.
|
||||
For more information about an error, try `rustc --explain E0307`.
|
||||
|
|
|
@ -15,7 +15,7 @@ fn bad_infer_fn<_>() {}
|
|||
|
||||
|
||||
fn main() {
|
||||
let a: All<_, _, _>;
|
||||
let a: All<_, _, _>; //~ ERROR struct takes 2 generic arguments but 3
|
||||
all_fn();
|
||||
let v: [u8; _];
|
||||
let v: [u8; 10] = [0; _];
|
||||
|
|
|
@ -19,6 +19,21 @@ LL | struct BadInfer<_>;
|
|||
= help: consider removing `_`, referring to it in a field, or using a marker such as `PhantomData`
|
||||
= help: if you intended `_` to be a const parameter, use `const _: usize` instead
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
error[E0107]: struct takes 2 generic arguments but 3 generic arguments were supplied
|
||||
--> $DIR/infer-arg-test.rs:18:10
|
||||
|
|
||||
LL | let a: All<_, _, _>;
|
||||
| ^^^ - help: remove this generic argument
|
||||
| |
|
||||
| expected 2 generic arguments
|
||||
|
|
||||
note: struct defined here, with 2 generic parameters: `T`, `N`
|
||||
--> $DIR/infer-arg-test.rs:3:8
|
||||
|
|
||||
LL | struct All<'a, T, const N: usize> {
|
||||
| ^^^ - --------------
|
||||
|
||||
For more information about this error, try `rustc --explain E0392`.
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0107, E0392.
|
||||
For more information about an error, try `rustc --explain E0107`.
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
const LENGTH: f64 = 2;
|
||||
//~^ ERROR mismatched types
|
||||
|
||||
struct Thing {
|
||||
f: [[f64; 2]; LENGTH],
|
||||
|
|
|
@ -1,9 +1,18 @@
|
|||
error[E0308]: mismatched types
|
||||
--> $DIR/issue-39974.rs:4:19
|
||||
--> $DIR/issue-39974.rs:5:19
|
||||
|
|
||||
LL | f: [[f64; 2]; LENGTH],
|
||||
| ^^^^^^ expected `usize`, found `f64`
|
||||
|
||||
error: aborting due to previous error
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/issue-39974.rs:1:21
|
||||
|
|
||||
LL | const LENGTH: f64 = 2;
|
||||
| ^
|
||||
| |
|
||||
| expected `f64`, found integer
|
||||
| help: use a float literal: `2.0`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0308`.
|
||||
|
|
|
@ -22,8 +22,8 @@ where
|
|||
type T = Either<Left::T, Right::T>;
|
||||
type TRef<'a> = Either<&'a Left::T, &'a Right::T>
|
||||
where
|
||||
<Left as HasChildrenOf>::T: 'a,
|
||||
<Right as HasChildrenOf>::T: 'a;
|
||||
<Left as HasChildrenOf>::T: 'a, //~ ERROR impl has stricter requirements than trait
|
||||
<Right as HasChildrenOf>::T: 'a; //~ ERROR impl has stricter requirements than trait
|
||||
|
||||
fn ref_children<'a>(&'a self) -> Vec<Self::TRef<'a>> {
|
||||
todo!()
|
||||
|
|
|
@ -9,5 +9,24 @@ LL | type TRef<'a>;
|
|||
= note: this bound is currently required to ensure that impls have maximum flexibility
|
||||
= note: we are soliciting feedback, see issue #87479 <https://github.com/rust-lang/rust/issues/87479> for more information
|
||||
|
||||
error: aborting due to previous error
|
||||
error[E0276]: impl has stricter requirements than trait
|
||||
--> $DIR/issue-86787.rs:25:37
|
||||
|
|
||||
LL | type TRef<'a>;
|
||||
| ------------- definition of `TRef` from trait
|
||||
...
|
||||
LL | <Left as HasChildrenOf>::T: 'a,
|
||||
| ^^ impl has extra requirement `<Left as HasChildrenOf>::T: 'a`
|
||||
|
||||
error[E0276]: impl has stricter requirements than trait
|
||||
--> $DIR/issue-86787.rs:26:38
|
||||
|
|
||||
LL | type TRef<'a>;
|
||||
| ------------- definition of `TRef` from trait
|
||||
...
|
||||
LL | <Right as HasChildrenOf>::T: 'a;
|
||||
| ^^ impl has extra requirement `<Right as HasChildrenOf>::T: 'a`
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0276`.
|
||||
|
|
|
@ -2,8 +2,8 @@ use std::marker::PhantomData;
|
|||
struct Foo<'a, 'b, T>(PhantomData<(&'a (), &'b (), T)>)
|
||||
where
|
||||
Foo<'short, 'out, T>: Convert<'a, 'b>;
|
||||
//~^ ERROR use of undeclared lifetime name
|
||||
//~| ERROR use of undeclared lifetime name `'out`
|
||||
//~^ ERROR use of undeclared lifetime name
|
||||
//~| ERROR use of undeclared lifetime name `'out`
|
||||
|
||||
trait Convert<'a, 'b>: Sized {
|
||||
fn cast(&'a self) -> &'b Self;
|
||||
|
@ -19,7 +19,7 @@ impl<'long: 'short, 'short, T> Convert<'long, 'b> for Foo<'short, 'out, T> {
|
|||
|
||||
fn badboi<'in_, 'out, T>(x: Foo<'in_, 'out, T>, sadness: &'in_ Foo<'short, 'out, T>) -> &'out T {
|
||||
//~^ ERROR use of undeclared lifetime name
|
||||
sadness.cast() //~ ERROR mismatched types
|
||||
sadness.cast()
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
|
@ -66,19 +66,6 @@ LL | fn badboi<'in_, 'out, T>(x: Foo<'in_, 'out, T>, sadness: &'in_ Foo<'short,
|
|||
| |
|
||||
| help: consider introducing lifetime `'short` here: `'short,`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/issue-107090.rs:22:5
|
||||
|
|
||||
LL | fn badboi<'in_, 'out, T>(x: Foo<'in_, 'out, T>, sadness: &'in_ Foo<'short, 'out, T>) -> &'out T {
|
||||
| - expected this type parameter ------- expected `&'out T` because of return type
|
||||
LL |
|
||||
LL | sadness.cast()
|
||||
| ^^^^^^^^^^^^^^ expected `&T`, found `&Foo<'_, '_, T>`
|
||||
|
|
||||
= note: expected reference `&'out T`
|
||||
found reference `&Foo<'_, '_, T>`
|
||||
error: aborting due to 6 previous errors
|
||||
|
||||
error: aborting due to 7 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0261, E0308.
|
||||
For more information about an error, try `rustc --explain E0261`.
|
||||
For more information about this error, try `rustc --explain E0261`.
|
||||
|
|
|
@ -22,6 +22,10 @@ help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to break the cycle
|
|||
LL | x: Bar<Box<Foo>>,
|
||||
| ++++ +
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
error: reached the recursion limit finding the struct tail for `Take`
|
||||
|
|
||||
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]`
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0072`.
|
||||
|
|
|
@ -10,4 +10,3 @@ struct Multiply<N, M> {
|
|||
}
|
||||
impl<N, M> TypeVal<usize> for Multiply<N, M> where N: TypeVal<VAL> {}
|
||||
//~^ ERROR cannot find type `VAL` in this scope
|
||||
//~| ERROR not all trait items implemented, missing: `VAL`
|
||||
|
|
|
@ -20,16 +20,6 @@ help: you might be missing a type parameter
|
|||
LL | impl<N, M, VAL> TypeVal<usize> for Multiply<N, M> where N: TypeVal<VAL> {}
|
||||
| +++++
|
||||
|
||||
error[E0046]: not all trait items implemented, missing: `VAL`
|
||||
--> $DIR/issue-77919.rs:11:1
|
||||
|
|
||||
LL | const VAL: T;
|
||||
| ------------ `VAL` from trait
|
||||
...
|
||||
LL | impl<N, M> TypeVal<usize> for Multiply<N, M> where N: TypeVal<VAL> {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `VAL` in implementation
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0046, E0412.
|
||||
For more information about an error, try `rustc --explain E0046`.
|
||||
For more information about this error, try `rustc --explain E0412`.
|
||||
|
|
|
@ -16,7 +16,8 @@ struct Other {
|
|||
|
||||
fn main() {
|
||||
unsafe {
|
||||
// FIXME(oli-obk): make this report a transmute error again.
|
||||
std::mem::transmute::<Option<()>, Option<&Other>>(None);
|
||||
//~^ ERROR cannot transmute between types of different sizes, or dependently-sized types
|
||||
//^ ERROR cannot transmute between types of different sizes, or dependently-sized types
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,16 +4,6 @@ error[E0412]: cannot find type `Missing` in this scope
|
|||
LL | Missing: Trait,
|
||||
| ^^^^^^^ not found in this scope
|
||||
|
||||
error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
|
||||
--> $DIR/cannot-transmute-unnormalizable-type.rs:19:9
|
||||
|
|
||||
LL | std::mem::transmute::<Option<()>, Option<&Other>>(None);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: source type: `Option<()>` (8 bits)
|
||||
= note: target type: `Option<&Other>` (unable to determine layout for `Other` because `<() as Trait>::RefTarget` cannot be normalized)
|
||||
error: aborting due to previous error
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0412, E0512.
|
||||
For more information about an error, try `rustc --explain E0412`.
|
||||
For more information about this error, try `rustc --explain E0412`.
|
||||
|
|
|
@ -5,5 +5,9 @@ fn f2<'a>(x: u8, y: Vec<&'a ...>) {}
|
|||
//~^ ERROR C-variadic type `...` may not be nested inside another type
|
||||
|
||||
fn main() {
|
||||
let _recovery_witness: () = 0; //~ ERROR mismatched types
|
||||
// While this is an error, wf-checks happen before typeck, and if any wf-checks
|
||||
// encountered errors, we do not continue to typeck, even if the items are
|
||||
// unrelated.
|
||||
// FIXME(oli-obk): make this report a type mismatch again.
|
||||
let _recovery_witness: () = 0;
|
||||
}
|
||||
|
|
|
@ -10,15 +10,6 @@ error[E0743]: C-variadic type `...` may not be nested inside another type
|
|||
LL | fn f2<'a>(x: u8, y: Vec<&'a ...>) {}
|
||||
| ^^^
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/variadic-ffi-nested-syntactic-fail.rs:8:33
|
||||
|
|
||||
LL | let _recovery_witness: () = 0;
|
||||
| -- ^ expected `()`, found integer
|
||||
| |
|
||||
| expected due to this
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0308, E0743.
|
||||
For more information about an error, try `rustc --explain E0308`.
|
||||
For more information about this error, try `rustc --explain E0743`.
|
||||
|
|
|
@ -22,6 +22,8 @@ pub fn main() {
|
|||
//~^ ERROR cannot find macro `Self` in this scope
|
||||
Foo { Self } => (),
|
||||
//~^ ERROR expected identifier, found keyword `Self`
|
||||
//~| ERROR mismatched types
|
||||
//~| ERROR `Foo` does not have a field named `Self`
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -31,19 +31,19 @@ LL | Foo { Self } => (),
|
|||
| ^^^^ expected identifier, found keyword
|
||||
|
||||
error: expected identifier, found keyword `Self`
|
||||
--> $DIR/self_type_keyword.rs:29:26
|
||||
--> $DIR/self_type_keyword.rs:31:26
|
||||
|
|
||||
LL | extern crate core as Self;
|
||||
| ^^^^ expected identifier, found keyword
|
||||
|
||||
error: expected identifier, found keyword `Self`
|
||||
--> $DIR/self_type_keyword.rs:34:32
|
||||
--> $DIR/self_type_keyword.rs:36:32
|
||||
|
|
||||
LL | use std::option::Option as Self;
|
||||
| ^^^^ expected identifier, found keyword
|
||||
|
||||
error: expected identifier, found keyword `Self`
|
||||
--> $DIR/self_type_keyword.rs:39:11
|
||||
--> $DIR/self_type_keyword.rs:41:11
|
||||
|
|
||||
LL | trait Self {}
|
||||
| ^^^^ expected identifier, found keyword
|
||||
|
@ -80,7 +80,22 @@ LL | struct Bar<'Self>;
|
|||
|
|
||||
= help: consider removing `'Self`, referring to it in a field, or using a marker such as `PhantomData`
|
||||
|
||||
error: aborting due to 12 previous errors
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/self_type_keyword.rs:23:9
|
||||
|
|
||||
LL | match 15 {
|
||||
| -- this expression has type `{integer}`
|
||||
...
|
||||
LL | Foo { Self } => (),
|
||||
| ^^^^^^^^^^^^ expected integer, found `Foo`
|
||||
|
||||
Some errors have detailed explanations: E0392, E0531.
|
||||
For more information about an error, try `rustc --explain E0392`.
|
||||
error[E0026]: struct `Foo` does not have a field named `Self`
|
||||
--> $DIR/self_type_keyword.rs:23:15
|
||||
|
|
||||
LL | Foo { Self } => (),
|
||||
| ^^^^ struct `Foo` does not have this field
|
||||
|
||||
error: aborting due to 14 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0026, E0308, E0392, E0531.
|
||||
For more information about an error, try `rustc --explain E0026`.
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
|
||||
trait Trait {
|
||||
fn func<const N: u32>() -> [ (); N ];
|
||||
fn func<const N: u32>() -> [ (); N ]; //~ ERROR mismatched types
|
||||
}
|
||||
|
||||
struct S {}
|
||||
|
|
|
@ -4,6 +4,12 @@ error[E0308]: mismatched types
|
|||
LL | fn func<const N: u32>() -> [ (); { () }] {
|
||||
| ^^ expected `usize`, found `()`
|
||||
|
||||
error: aborting due to previous error
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/const-in-impl-fn-return-type.rs:8:38
|
||||
|
|
||||
LL | fn func<const N: u32>() -> [ (); N ];
|
||||
| ^ expected `usize`, found `u32`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0308`.
|
||||
|
|
Loading…
Add table
Reference in a new issue