mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-17 01:13:11 +00:00
Auto merge of #111526 - Dylan-DPC:rollup-h75agro, r=Dylan-DPC
Rollup of 6 pull requests Successful merges: - #110454 (Require impl Trait in associated types to appear in method signatures) - #111096 (Add support for `cfg(overflow_checks)`) - #111451 (Note user-facing types of coercion failure) - #111469 (Fix data race in llvm source code coverage) - #111494 (Encode `VariantIdx` so we can decode ADT variants in the right order) - #111499 (asm: loongarch64: Drop efiapi) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
69fef92ab2
@ -305,7 +305,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
);
|
||||
this.arena.alloc(this.ty(span, hir::TyKind::Err(guar)))
|
||||
}
|
||||
Some(ty) => this.lower_ty(ty, &ImplTraitContext::TypeAliasesOpaqueTy),
|
||||
Some(ty) => this.lower_ty(
|
||||
ty,
|
||||
&ImplTraitContext::TypeAliasesOpaqueTy { in_assoc_ty: false },
|
||||
),
|
||||
},
|
||||
);
|
||||
hir::ItemKind::TyAlias(ty, generics)
|
||||
@ -852,7 +855,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
hir::ImplItemKind::Type(ty)
|
||||
}
|
||||
Some(ty) => {
|
||||
let ty = this.lower_ty(ty, &ImplTraitContext::TypeAliasesOpaqueTy);
|
||||
let ty = this.lower_ty(
|
||||
ty,
|
||||
&ImplTraitContext::TypeAliasesOpaqueTy { in_assoc_ty: true },
|
||||
);
|
||||
hir::ImplItemKind::Type(ty)
|
||||
}
|
||||
},
|
||||
|
@ -247,7 +247,7 @@ enum ImplTraitContext {
|
||||
in_trait: bool,
|
||||
},
|
||||
/// Impl trait in type aliases.
|
||||
TypeAliasesOpaqueTy,
|
||||
TypeAliasesOpaqueTy { in_assoc_ty: bool },
|
||||
/// `impl Trait` is unstably accepted in this position.
|
||||
FeatureGated(ImplTraitPosition, Symbol),
|
||||
/// `impl Trait` is not accepted in this position.
|
||||
@ -1407,14 +1407,15 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
*in_trait,
|
||||
itctx,
|
||||
),
|
||||
ImplTraitContext::TypeAliasesOpaqueTy => self.lower_opaque_impl_trait(
|
||||
span,
|
||||
hir::OpaqueTyOrigin::TyAlias,
|
||||
*def_node_id,
|
||||
bounds,
|
||||
false,
|
||||
itctx,
|
||||
),
|
||||
&ImplTraitContext::TypeAliasesOpaqueTy { in_assoc_ty } => self
|
||||
.lower_opaque_impl_trait(
|
||||
span,
|
||||
hir::OpaqueTyOrigin::TyAlias { in_assoc_ty },
|
||||
*def_node_id,
|
||||
bounds,
|
||||
false,
|
||||
itctx,
|
||||
),
|
||||
ImplTraitContext::Universal => {
|
||||
let span = t.span;
|
||||
self.create_def(
|
||||
@ -1534,13 +1535,16 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
// If this came from a TAIT (as opposed to a function that returns an RPIT), we only want
|
||||
// to capture the lifetimes that appear in the bounds. So visit the bounds to find out
|
||||
// exactly which ones those are.
|
||||
let lifetimes_to_remap = if origin == hir::OpaqueTyOrigin::TyAlias {
|
||||
// in a TAIT like `type Foo<'a> = impl Foo<'a>`, we don't keep all the lifetime parameters
|
||||
Vec::new()
|
||||
} else {
|
||||
// in fn return position, like the `fn test<'a>() -> impl Debug + 'a` example,
|
||||
// we only keep the lifetimes that appear in the `impl Debug` itself:
|
||||
lifetime_collector::lifetimes_in_bounds(&self.resolver, bounds)
|
||||
let lifetimes_to_remap = match origin {
|
||||
hir::OpaqueTyOrigin::TyAlias { .. } => {
|
||||
// in a TAIT like `type Foo<'a> = impl Foo<'a>`, we don't keep all the lifetime parameters
|
||||
Vec::new()
|
||||
}
|
||||
hir::OpaqueTyOrigin::AsyncFn(..) | hir::OpaqueTyOrigin::FnReturn(..) => {
|
||||
// in fn return position, like the `fn test<'a>() -> impl Debug + 'a` example,
|
||||
// we only keep the lifetimes that appear in the `impl Debug` itself:
|
||||
lifetime_collector::lifetimes_in_bounds(&self.resolver, bounds)
|
||||
}
|
||||
};
|
||||
debug!(?lifetimes_to_remap);
|
||||
|
||||
|
@ -265,7 +265,7 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
|
||||
|
||||
// Only check this for TAIT. RPIT already supports `tests/ui/impl-trait/nested-return-type2.rs`
|
||||
// on stable and we'd break that.
|
||||
let OpaqueTyOrigin::TyAlias = origin else {
|
||||
let OpaqueTyOrigin::TyAlias { .. } = origin else {
|
||||
return definition_ty;
|
||||
};
|
||||
let def_id = opaque_type_key.def_id;
|
||||
@ -360,7 +360,7 @@ fn check_opaque_type_parameter_valid(
|
||||
// which would error here on all of the `'static` args.
|
||||
OpaqueTyOrigin::FnReturn(..) | OpaqueTyOrigin::AsyncFn(..) => return Ok(()),
|
||||
// Check these
|
||||
OpaqueTyOrigin::TyAlias => {}
|
||||
OpaqueTyOrigin::TyAlias { .. } => {}
|
||||
}
|
||||
let opaque_generics = tcx.generics_of(opaque_type_key.def_id);
|
||||
let mut seen_params: FxIndexMap<_, Vec<_>> = FxIndexMap::default();
|
||||
|
@ -321,6 +321,8 @@ declare_features! (
|
||||
(active, c_unwind, "1.52.0", Some(74990), None),
|
||||
/// Allows using C-variadics.
|
||||
(active, c_variadic, "1.34.0", Some(44930), None),
|
||||
/// Allows the use of `#[cfg(overflow_checks)` to check if integer overflow behaviour.
|
||||
(active, cfg_overflow_checks, "CURRENT_RUSTC_VERSION", Some(111466), None),
|
||||
/// Allows the use of `#[cfg(sanitize = "option")]`; set when -Zsanitizer is used.
|
||||
(active, cfg_sanitize, "1.41.0", Some(39699), None),
|
||||
/// Allows `cfg(target_abi = "...")`.
|
||||
|
@ -24,6 +24,7 @@ pub type GatedCfg = (Symbol, Symbol, GateFn);
|
||||
/// `cfg(...)`'s that are feature gated.
|
||||
const GATED_CFGS: &[GatedCfg] = &[
|
||||
// (name in cfg, feature, function to check if the feature is enabled)
|
||||
(sym::overflow_checks, sym::cfg_overflow_checks, cfg_fn!(cfg_overflow_checks)),
|
||||
(sym::target_abi, sym::cfg_target_abi, cfg_fn!(cfg_target_abi)),
|
||||
(sym::target_thread_local, sym::cfg_target_thread_local, cfg_fn!(cfg_target_thread_local)),
|
||||
(
|
||||
|
@ -2662,7 +2662,10 @@ pub enum OpaqueTyOrigin {
|
||||
/// `async fn`
|
||||
AsyncFn(LocalDefId),
|
||||
/// type aliases: `type Foo = impl Trait;`
|
||||
TyAlias,
|
||||
TyAlias {
|
||||
/// associated types in impl blocks for traits.
|
||||
in_assoc_ty: bool,
|
||||
},
|
||||
}
|
||||
|
||||
/// The various kinds of types recognized by the compiler.
|
||||
|
@ -397,7 +397,7 @@ fn check_opaque_meets_bounds<'tcx>(
|
||||
) {
|
||||
let defining_use_anchor = match *origin {
|
||||
hir::OpaqueTyOrigin::FnReturn(did) | hir::OpaqueTyOrigin::AsyncFn(did) => did,
|
||||
hir::OpaqueTyOrigin::TyAlias => def_id,
|
||||
hir::OpaqueTyOrigin::TyAlias { .. } => tcx.impl_trait_parent(def_id),
|
||||
};
|
||||
let param_env = tcx.param_env(defining_use_anchor);
|
||||
|
||||
@ -455,10 +455,10 @@ fn check_opaque_meets_bounds<'tcx>(
|
||||
// They can only be referenced as `<Opaque<T> as Trait<&'static T>>::AssocTy`.
|
||||
// We don't have to check them here because their well-formedness follows from the WF of
|
||||
// the projection input types in the defining- and use-sites.
|
||||
hir::OpaqueTyOrigin::TyAlias
|
||||
hir::OpaqueTyOrigin::TyAlias { .. }
|
||||
if tcx.def_kind(tcx.parent(def_id.to_def_id())) == DefKind::OpaqueTy => {}
|
||||
// Can have different predicates to their defining use
|
||||
hir::OpaqueTyOrigin::TyAlias => {
|
||||
hir::OpaqueTyOrigin::TyAlias { .. } => {
|
||||
let wf_tys = ocx.assumed_wf_types(param_env, span, def_id);
|
||||
let implied_bounds = infcx.implied_bounds_tys(param_env, def_id, wf_tys);
|
||||
let outlives_env = OutlivesEnvironment::with_bounds(param_env, implied_bounds);
|
||||
|
@ -6,7 +6,7 @@ use rustc_errors::{struct_span_err, ErrorGuaranteed};
|
||||
use rustc_infer::infer::outlives::env::OutlivesEnvironment;
|
||||
use rustc_infer::infer::{RegionResolutionError, TyCtxtInferExt};
|
||||
use rustc_middle::ty::subst::SubstsRef;
|
||||
use rustc_middle::ty::util::IgnoreRegions;
|
||||
use rustc_middle::ty::util::CheckRegions;
|
||||
use rustc_middle::ty::{self, TyCtxt};
|
||||
use rustc_trait_selection::traits::{self, ObligationCtxt};
|
||||
|
||||
@ -81,7 +81,7 @@ fn ensure_drop_params_and_item_params_correspond<'tcx>(
|
||||
self_type_did: DefId,
|
||||
adt_to_impl_substs: SubstsRef<'tcx>,
|
||||
) -> Result<(), ErrorGuaranteed> {
|
||||
let Err(arg) = tcx.uses_unique_generic_params(adt_to_impl_substs, IgnoreRegions::No) else {
|
||||
let Err(arg) = tcx.uses_unique_generic_params(adt_to_impl_substs, CheckRegions::OnlyEarlyBound) else {
|
||||
return Ok(())
|
||||
};
|
||||
|
||||
|
@ -6,7 +6,7 @@ use rustc_errors::{struct_span_err, DelayDm};
|
||||
use rustc_errors::{Diagnostic, ErrorGuaranteed};
|
||||
use rustc_hir as hir;
|
||||
use rustc_middle::ty::subst::InternalSubsts;
|
||||
use rustc_middle::ty::util::IgnoreRegions;
|
||||
use rustc_middle::ty::util::CheckRegions;
|
||||
use rustc_middle::ty::{
|
||||
self, AliasKind, ImplPolarity, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt,
|
||||
TypeVisitor,
|
||||
@ -507,7 +507,7 @@ fn lint_auto_trait_impl<'tcx>(
|
||||
// Impls which completely cover a given root type are fine as they
|
||||
// disable auto impls entirely. So only lint if the substs
|
||||
// are not a permutation of the identity substs.
|
||||
let Err(arg) = tcx.uses_unique_generic_params(substs, IgnoreRegions::Yes) else {
|
||||
let Err(arg) = tcx.uses_unique_generic_params(substs, CheckRegions::No) else {
|
||||
// ok
|
||||
return;
|
||||
};
|
||||
|
@ -1483,7 +1483,7 @@ fn generator_kind(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<hir::GeneratorK
|
||||
fn is_type_alias_impl_trait<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> bool {
|
||||
match tcx.hir().get_by_def_id(def_id) {
|
||||
Node::Item(hir::Item { kind: hir::ItemKind::OpaqueTy(opaque), .. }) => {
|
||||
matches!(opaque.origin, hir::OpaqueTyOrigin::TyAlias)
|
||||
matches!(opaque.origin, hir::OpaqueTyOrigin::TyAlias { .. })
|
||||
}
|
||||
_ => bug!("tried getting opaque_ty_origin for non-opaque: {:?}", def_id),
|
||||
}
|
||||
|
@ -159,7 +159,10 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
|
||||
}
|
||||
Some(fn_def_id.to_def_id())
|
||||
}
|
||||
ItemKind::OpaqueTy(hir::OpaqueTy { origin: hir::OpaqueTyOrigin::TyAlias, .. }) => {
|
||||
ItemKind::OpaqueTy(hir::OpaqueTy {
|
||||
origin: hir::OpaqueTyOrigin::TyAlias { .. },
|
||||
..
|
||||
}) => {
|
||||
let parent_id = tcx.hir().get_parent_item(hir_id);
|
||||
assert_ne!(parent_id, hir::CRATE_OWNER_ID);
|
||||
debug!("generics_of: parent of opaque ty {:?} is {:?}", def_id, parent_id);
|
||||
|
@ -721,7 +721,7 @@ pub(super) fn type_param_predicates(
|
||||
| ItemKind::TyAlias(_, generics)
|
||||
| ItemKind::OpaqueTy(OpaqueTy {
|
||||
generics,
|
||||
origin: hir::OpaqueTyOrigin::TyAlias,
|
||||
origin: hir::OpaqueTyOrigin::TyAlias { .. },
|
||||
..
|
||||
})
|
||||
| ItemKind::Enum(_, generics)
|
||||
|
@ -526,7 +526,8 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
|
||||
});
|
||||
}
|
||||
hir::ItemKind::OpaqueTy(hir::OpaqueTy {
|
||||
origin: hir::OpaqueTyOrigin::TyAlias, ..
|
||||
origin: hir::OpaqueTyOrigin::TyAlias { .. },
|
||||
..
|
||||
}) => {
|
||||
// Opaque types are visited when we visit the
|
||||
// `TyKind::OpaqueDef`, so that they have the lifetimes from
|
||||
@ -707,7 +708,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
|
||||
let opaque_ty = self.tcx.hir().item(item_id);
|
||||
match &opaque_ty.kind {
|
||||
hir::ItemKind::OpaqueTy(hir::OpaqueTy {
|
||||
origin: hir::OpaqueTyOrigin::TyAlias,
|
||||
origin: hir::OpaqueTyOrigin::TyAlias { .. },
|
||||
..
|
||||
}) => {
|
||||
intravisit::walk_ty(self, ty);
|
||||
|
@ -426,9 +426,10 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<Ty
|
||||
let substs = InternalSubsts::identity_for_item(tcx, def_id);
|
||||
tcx.mk_adt(def, substs)
|
||||
}
|
||||
ItemKind::OpaqueTy(OpaqueTy { origin: hir::OpaqueTyOrigin::TyAlias, .. }) => {
|
||||
find_opaque_ty_constraints_for_tait(tcx, def_id)
|
||||
}
|
||||
ItemKind::OpaqueTy(OpaqueTy {
|
||||
origin: hir::OpaqueTyOrigin::TyAlias { .. },
|
||||
..
|
||||
}) => find_opaque_ty_constraints_for_tait(tcx, def_id),
|
||||
// Opaque types desugared from `impl Trait`.
|
||||
ItemKind::OpaqueTy(OpaqueTy {
|
||||
origin:
|
||||
|
@ -2,6 +2,7 @@ use super::TypeErrCtxt;
|
||||
use rustc_errors::Applicability::{MachineApplicable, MaybeIncorrect};
|
||||
use rustc_errors::{pluralize, Diagnostic, MultiSpan};
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def::DefKind;
|
||||
use rustc_middle::traits::ObligationCauseCode;
|
||||
use rustc_middle::ty::error::ExpectedFound;
|
||||
use rustc_middle::ty::print::Printer;
|
||||
@ -256,6 +257,15 @@ impl<T> Trait<T> for X {
|
||||
);
|
||||
}
|
||||
}
|
||||
(ty::Alias(ty::Opaque, alias), _) | (_, ty::Alias(ty::Opaque, alias)) if alias.def_id.is_local() && matches!(tcx.def_kind(body_owner_def_id), DefKind::AssocFn | DefKind::AssocConst) => {
|
||||
if tcx.is_type_alias_impl_trait(alias.def_id) {
|
||||
if !tcx.opaque_types_defined_by(body_owner_def_id.expect_local()).contains(&alias.def_id.expect_local()) {
|
||||
diag.span_note(tcx.def_span(body_owner_def_id), "\
|
||||
this item must have the opaque type in its signature \
|
||||
in order to be able to register hidden types");
|
||||
}
|
||||
}
|
||||
}
|
||||
(ty::FnPtr(_), ty::FnDef(def, _))
|
||||
if let hir::def::DefKind::Fn = tcx.def_kind(def) => {
|
||||
diag.note(
|
||||
|
@ -149,7 +149,7 @@ impl<'tcx> InferCtxt<'tcx> {
|
||||
// no one encounters it in practice.
|
||||
// It does occur however in `fn fut() -> impl Future<Output = i32> { async { 42 } }`,
|
||||
// where it is of no concern, so we only check for TAITs.
|
||||
if let Some(OpaqueTyOrigin::TyAlias) =
|
||||
if let Some(OpaqueTyOrigin::TyAlias { .. }) =
|
||||
b_def_id.as_local().and_then(|b_def_id| self.opaque_type_origin(b_def_id))
|
||||
{
|
||||
self.tcx.sess.emit_err(OpaqueHiddenTypeDiag {
|
||||
@ -381,8 +381,12 @@ impl<'tcx> InferCtxt<'tcx> {
|
||||
// Anonymous `impl Trait`
|
||||
hir::OpaqueTyOrigin::FnReturn(parent) => parent == parent_def_id,
|
||||
// Named `type Foo = impl Bar;`
|
||||
hir::OpaqueTyOrigin::TyAlias => {
|
||||
may_define_opaque_type(self.tcx, parent_def_id, opaque_hir_id)
|
||||
hir::OpaqueTyOrigin::TyAlias { in_assoc_ty } => {
|
||||
if in_assoc_ty {
|
||||
self.tcx.opaque_types_defined_by(parent_def_id).contains(&def_id)
|
||||
} else {
|
||||
may_define_opaque_type(self.tcx, parent_def_id, opaque_hir_id)
|
||||
}
|
||||
}
|
||||
};
|
||||
in_definition_scope.then_some(origin)
|
||||
|
@ -745,6 +745,9 @@ LLVMRustOptimize(
|
||||
if (InstrProfileOutput) {
|
||||
Options.InstrProfileOutput = InstrProfileOutput;
|
||||
}
|
||||
// cargo run tests in multhreading mode by default
|
||||
// so use atomics for coverage counters
|
||||
Options.Atomic = true;
|
||||
MPM.addPass(InstrProfiling(Options, false));
|
||||
}
|
||||
);
|
||||
|
@ -856,7 +856,12 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
|
||||
ty::EarlyBinder(&*output)
|
||||
}
|
||||
|
||||
fn get_variant(self, kind: &DefKind, index: DefIndex, parent_did: DefId) -> ty::VariantDef {
|
||||
fn get_variant(
|
||||
self,
|
||||
kind: DefKind,
|
||||
index: DefIndex,
|
||||
parent_did: DefId,
|
||||
) -> (VariantIdx, ty::VariantDef) {
|
||||
let adt_kind = match kind {
|
||||
DefKind::Variant => ty::AdtKind::Enum,
|
||||
DefKind::Struct => ty::AdtKind::Struct,
|
||||
@ -870,22 +875,25 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
|
||||
if adt_kind == ty::AdtKind::Enum { Some(self.local_def_id(index)) } else { None };
|
||||
let ctor = data.ctor.map(|(kind, index)| (kind, self.local_def_id(index)));
|
||||
|
||||
ty::VariantDef::new(
|
||||
self.item_name(index),
|
||||
variant_did,
|
||||
ctor,
|
||||
data.discr,
|
||||
self.get_associated_item_or_field_def_ids(index)
|
||||
.map(|did| ty::FieldDef {
|
||||
did,
|
||||
name: self.item_name(did.index),
|
||||
vis: self.get_visibility(did.index),
|
||||
})
|
||||
.collect(),
|
||||
adt_kind,
|
||||
parent_did,
|
||||
false,
|
||||
data.is_non_exhaustive,
|
||||
(
|
||||
data.idx,
|
||||
ty::VariantDef::new(
|
||||
self.item_name(index),
|
||||
variant_did,
|
||||
ctor,
|
||||
data.discr,
|
||||
self.get_associated_item_or_field_def_ids(index)
|
||||
.map(|did| ty::FieldDef {
|
||||
did,
|
||||
name: self.item_name(did.index),
|
||||
vis: self.get_visibility(did.index),
|
||||
})
|
||||
.collect(),
|
||||
adt_kind,
|
||||
parent_did,
|
||||
false,
|
||||
data.is_non_exhaustive,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
@ -901,7 +909,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
|
||||
};
|
||||
let repr = self.root.tables.repr_options.get(self, item_id).unwrap().decode(self);
|
||||
|
||||
let variants = if let ty::AdtKind::Enum = adt_kind {
|
||||
let mut variants: Vec<_> = if let ty::AdtKind::Enum = adt_kind {
|
||||
self.root
|
||||
.tables
|
||||
.module_children_non_reexports
|
||||
@ -912,15 +920,22 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
|
||||
let kind = self.def_kind(index);
|
||||
match kind {
|
||||
DefKind::Ctor(..) => None,
|
||||
_ => Some(self.get_variant(&kind, index, did)),
|
||||
_ => Some(self.get_variant(kind, index, did)),
|
||||
}
|
||||
})
|
||||
.collect()
|
||||
} else {
|
||||
std::iter::once(self.get_variant(&kind, item_id, did)).collect()
|
||||
std::iter::once(self.get_variant(kind, item_id, did)).collect()
|
||||
};
|
||||
|
||||
tcx.mk_adt_def(did, adt_kind, variants, repr)
|
||||
variants.sort_by_key(|(idx, _)| *idx);
|
||||
|
||||
tcx.mk_adt_def(
|
||||
did,
|
||||
adt_kind,
|
||||
variants.into_iter().map(|(_, variant)| variant).collect(),
|
||||
repr,
|
||||
)
|
||||
}
|
||||
|
||||
fn get_visibility(self, id: DefIndex) -> Visibility<DefId> {
|
||||
|
@ -1375,9 +1375,10 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
|
||||
// Therefore, the loop over variants will encode its fields as the adt's children.
|
||||
}
|
||||
|
||||
for variant in adt_def.variants().iter() {
|
||||
for (idx, variant) in adt_def.variants().iter_enumerated() {
|
||||
let data = VariantData {
|
||||
discr: variant.discr,
|
||||
idx,
|
||||
ctor: variant.ctor.map(|(kind, def_id)| (kind, def_id.index)),
|
||||
is_non_exhaustive: variant.is_field_list_non_exhaustive(),
|
||||
};
|
||||
@ -1641,9 +1642,10 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
|
||||
}
|
||||
hir::ItemKind::OpaqueTy(ref opaque) => {
|
||||
self.encode_explicit_item_bounds(def_id);
|
||||
self.tables
|
||||
.is_type_alias_impl_trait
|
||||
.set(def_id.index, matches!(opaque.origin, hir::OpaqueTyOrigin::TyAlias));
|
||||
self.tables.is_type_alias_impl_trait.set(
|
||||
def_id.index,
|
||||
matches!(opaque.origin, hir::OpaqueTyOrigin::TyAlias { .. }),
|
||||
);
|
||||
}
|
||||
hir::ItemKind::Impl(hir::Impl { defaultness, constness, .. }) => {
|
||||
self.tables.impl_defaultness.set_some(def_id.index, *defaultness);
|
||||
|
@ -31,6 +31,7 @@ use rustc_span::edition::Edition;
|
||||
use rustc_span::hygiene::{ExpnIndex, MacroKind};
|
||||
use rustc_span::symbol::{Ident, Symbol};
|
||||
use rustc_span::{self, ExpnData, ExpnHash, ExpnId, Span};
|
||||
use rustc_target::abi::VariantIdx;
|
||||
use rustc_target::spec::{PanicStrategy, TargetTriple};
|
||||
|
||||
use std::marker::PhantomData;
|
||||
@ -430,6 +431,7 @@ define_tables! {
|
||||
|
||||
#[derive(TyEncodable, TyDecodable)]
|
||||
struct VariantData {
|
||||
idx: VariantIdx,
|
||||
discr: ty::VariantDiscr,
|
||||
/// If this is unit or tuple-variant/struct, then this is the index of the ctor id.
|
||||
ctor: Option<(CtorKind, DefIndex)>,
|
||||
|
@ -172,6 +172,10 @@ impl EraseType for ty::Binder<'_, ty::FnSig<'_>> {
|
||||
type Result = [u8; size_of::<ty::Binder<'static, ty::FnSig<'static>>>()];
|
||||
}
|
||||
|
||||
impl EraseType for ty::Binder<'_, &'_ ty::List<Ty<'_>>> {
|
||||
type Result = [u8; size_of::<ty::Binder<'static, &'static ty::List<Ty<'static>>>>()];
|
||||
}
|
||||
|
||||
impl<T0, T1> EraseType for (&'_ T0, &'_ T1) {
|
||||
type Result = [u8; size_of::<(&'static (), &'static ())>()];
|
||||
}
|
||||
|
@ -236,6 +236,15 @@ rustc_queries! {
|
||||
cache_on_disk_if { key.is_local() }
|
||||
}
|
||||
|
||||
query opaque_types_defined_by(
|
||||
key: LocalDefId
|
||||
) -> &'tcx [LocalDefId] {
|
||||
desc {
|
||||
|tcx| "computing the opaque types defined by `{}`",
|
||||
tcx.def_path_str(key.to_def_id())
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the list of bounds that can be used for
|
||||
/// `SelectionCandidate::ProjectionCandidate(_)` and
|
||||
/// `ProjectionTyCandidate::TraitDef`.
|
||||
|
@ -281,9 +281,6 @@ pub enum ObligationCauseCode<'tcx> {
|
||||
/// A type like `Box<Foo<'a> + 'b>` is WF only if `'b: 'a`.
|
||||
ObjectTypeBound(Ty<'tcx>, ty::Region<'tcx>),
|
||||
|
||||
/// Obligation incurred due to an object cast.
|
||||
ObjectCastObligation(/* Concrete type */ Ty<'tcx>, /* Object type */ Ty<'tcx>),
|
||||
|
||||
/// Obligation incurred due to a coercion.
|
||||
Coercion {
|
||||
source: Ty<'tcx>,
|
||||
|
@ -2476,6 +2476,18 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the `DefId` of the item within which the `impl Trait` is declared.
|
||||
/// For type-alias-impl-trait this is the `type` alias.
|
||||
/// For impl-trait-in-assoc-type this is the assoc type.
|
||||
/// For return-position-impl-trait this is the function.
|
||||
pub fn impl_trait_parent(self, mut def_id: LocalDefId) -> LocalDefId {
|
||||
// Find the surrounding item (type alias or assoc type)
|
||||
while let DefKind::OpaqueTy = self.def_kind(def_id) {
|
||||
def_id = self.local_parent(def_id);
|
||||
}
|
||||
def_id
|
||||
}
|
||||
|
||||
pub fn impl_method_has_trait_impl_trait_tys(self, def_id: DefId) -> bool {
|
||||
if self.def_kind(def_id) != DefKind::AssocFn {
|
||||
return false;
|
||||
@ -2520,7 +2532,7 @@ pub fn is_impl_trait_defn(tcx: TyCtxt<'_>, def_id: DefId) -> Option<LocalDefId>
|
||||
hir::OpaqueTyOrigin::FnReturn(parent) | hir::OpaqueTyOrigin::AsyncFn(parent) => {
|
||||
Some(parent)
|
||||
}
|
||||
hir::OpaqueTyOrigin::TyAlias => None,
|
||||
hir::OpaqueTyOrigin::TyAlias { .. } => None,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -32,7 +32,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
///
|
||||
/// This should only be used outside of type inference. For example,
|
||||
/// it assumes that normalization will succeed.
|
||||
#[tracing::instrument(level = "debug", skip(self, param_env))]
|
||||
#[tracing::instrument(level = "debug", skip(self, param_env), ret)]
|
||||
pub fn normalize_erasing_regions<T>(self, param_env: ty::ParamEnv<'tcx>, value: T) -> T
|
||||
where
|
||||
T: TypeFoldable<TyCtxt<'tcx>>,
|
||||
|
@ -1265,7 +1265,7 @@ impl<'tcx> AliasTy<'tcx> {
|
||||
|
||||
/// Extracts the underlying trait reference and own substs from this projection.
|
||||
/// For example, if this is a projection of `<T as StreamingIterator>::Item<'a>`,
|
||||
/// then this function would return a `T: Iterator` trait reference and `['a]` as the own substs
|
||||
/// then this function would return a `T: StreamingIterator` trait reference and `['a]` as the own substs
|
||||
pub fn trait_ref_and_own_substs(
|
||||
self,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
|
@ -34,9 +34,14 @@ pub struct Discr<'tcx> {
|
||||
|
||||
/// Used as an input to [`TyCtxt::uses_unique_generic_params`].
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||||
pub enum IgnoreRegions {
|
||||
Yes,
|
||||
pub enum CheckRegions {
|
||||
No,
|
||||
/// Only permit early bound regions. This is useful for Adts which
|
||||
/// can never have late bound regions.
|
||||
OnlyEarlyBound,
|
||||
/// Permit both late bound and early bound regions. Use this for functions,
|
||||
/// which frequently have late bound regions.
|
||||
Bound,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
@ -468,21 +473,28 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
pub fn uses_unique_generic_params(
|
||||
self,
|
||||
substs: SubstsRef<'tcx>,
|
||||
ignore_regions: IgnoreRegions,
|
||||
ignore_regions: CheckRegions,
|
||||
) -> Result<(), NotUniqueParam<'tcx>> {
|
||||
let mut seen = GrowableBitSet::default();
|
||||
let mut seen_late = FxHashSet::default();
|
||||
for arg in substs {
|
||||
match arg.unpack() {
|
||||
GenericArgKind::Lifetime(lt) => {
|
||||
if ignore_regions == IgnoreRegions::No {
|
||||
let ty::ReEarlyBound(p) = lt.kind() else {
|
||||
return Err(NotUniqueParam::NotParam(lt.into()))
|
||||
};
|
||||
GenericArgKind::Lifetime(lt) => match (ignore_regions, lt.kind()) {
|
||||
(CheckRegions::Bound, ty::ReLateBound(di, reg)) => {
|
||||
if !seen_late.insert((di, reg)) {
|
||||
return Err(NotUniqueParam::DuplicateParam(lt.into()));
|
||||
}
|
||||
}
|
||||
(CheckRegions::OnlyEarlyBound | CheckRegions::Bound, ty::ReEarlyBound(p)) => {
|
||||
if !seen.insert(p.index) {
|
||||
return Err(NotUniqueParam::DuplicateParam(lt.into()));
|
||||
}
|
||||
}
|
||||
}
|
||||
(CheckRegions::OnlyEarlyBound | CheckRegions::Bound, _) => {
|
||||
return Err(NotUniqueParam::NotParam(lt.into()));
|
||||
}
|
||||
(CheckRegions::No, _) => {}
|
||||
},
|
||||
GenericArgKind::Type(t) => match t.kind() {
|
||||
ty::Param(p) => {
|
||||
if !seen.insert(p.index) {
|
||||
|
@ -1060,6 +1060,9 @@ fn default_configuration(sess: &Session) -> CrateConfig {
|
||||
if sess.opts.debug_assertions {
|
||||
ret.insert((sym::debug_assertions, None));
|
||||
}
|
||||
if sess.overflow_checks() {
|
||||
ret.insert((sym::overflow_checks, None));
|
||||
}
|
||||
// JUSTIFICATION: before wrapper fn is available
|
||||
#[allow(rustc::bad_opt_access)]
|
||||
if sess.opts.crate_types.contains(&CrateType::ProcMacro) {
|
||||
@ -1209,6 +1212,7 @@ impl CrateCheckConfig {
|
||||
sym::windows,
|
||||
sym::proc_macro,
|
||||
sym::debug_assertions,
|
||||
sym::overflow_checks,
|
||||
sym::target_thread_local,
|
||||
] {
|
||||
self.expecteds.entry(name).or_insert_with(no_values);
|
||||
|
@ -463,6 +463,7 @@ symbols! {
|
||||
cfg_doctest,
|
||||
cfg_eval,
|
||||
cfg_hide,
|
||||
cfg_overflow_checks,
|
||||
cfg_panic,
|
||||
cfg_sanitize,
|
||||
cfg_target_abi,
|
||||
@ -1065,6 +1066,7 @@ symbols! {
|
||||
or_patterns,
|
||||
other,
|
||||
out,
|
||||
overflow_checks,
|
||||
overlapping_marker_traits,
|
||||
owned_box,
|
||||
packed,
|
||||
|
@ -882,8 +882,8 @@ impl InlineAsmClobberAbi {
|
||||
_ => Err(&["C", "system", "efiapi"]),
|
||||
},
|
||||
InlineAsmArch::LoongArch64 => match name {
|
||||
"C" | "system" | "efiapi" => Ok(InlineAsmClobberAbi::LoongArch),
|
||||
_ => Err(&["C", "system", "efiapi"]),
|
||||
"C" | "system" => Ok(InlineAsmClobberAbi::LoongArch),
|
||||
_ => Err(&["C", "system"]),
|
||||
},
|
||||
_ => Err(&[]),
|
||||
}
|
||||
|
@ -797,9 +797,17 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
||||
err.span_label(span, explanation);
|
||||
}
|
||||
|
||||
if let ObligationCauseCode::ObjectCastObligation(concrete_ty, obj_ty) = obligation.cause.code().peel_derives() &&
|
||||
Some(trait_ref.def_id()) == self.tcx.lang_items().sized_trait() {
|
||||
self.suggest_borrowing_for_object_cast(&mut err, &root_obligation, *concrete_ty, *obj_ty);
|
||||
if let ObligationCauseCode::Coercion { source, target } =
|
||||
*obligation.cause.code().peel_derives()
|
||||
{
|
||||
if Some(trait_ref.def_id()) == self.tcx.lang_items().sized_trait() {
|
||||
self.suggest_borrowing_for_object_cast(
|
||||
&mut err,
|
||||
&root_obligation,
|
||||
source,
|
||||
target,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
let UnsatisfiedConst(unsatisfied_const) = self
|
||||
@ -1510,7 +1518,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
||||
| ObligationCauseCode::BindingObligation(_, _)
|
||||
| ObligationCauseCode::ExprItemObligation(..)
|
||||
| ObligationCauseCode::ExprBindingObligation(..)
|
||||
| ObligationCauseCode::ObjectCastObligation(..)
|
||||
| ObligationCauseCode::Coercion { .. }
|
||||
| ObligationCauseCode::OpaqueType
|
||||
);
|
||||
|
||||
|
@ -1442,8 +1442,9 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
||||
err: &mut Diagnostic,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
self_ty: Ty<'tcx>,
|
||||
object_ty: Ty<'tcx>,
|
||||
target_ty: Ty<'tcx>,
|
||||
) {
|
||||
let ty::Ref(_, object_ty, hir::Mutability::Not) = target_ty.kind() else { return; };
|
||||
let ty::Dynamic(predicates, _, ty::Dyn) = object_ty.kind() else { return; };
|
||||
let self_ref_ty = self.tcx.mk_imm_ref(self.tcx.lifetimes.re_erased, self_ty);
|
||||
|
||||
@ -1458,7 +1459,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
||||
err.span_suggestion(
|
||||
obligation.cause.span.shrink_to_lo(),
|
||||
format!(
|
||||
"consider borrowing the value, since `&{self_ty}` can be coerced into `{object_ty}`"
|
||||
"consider borrowing the value, since `&{self_ty}` can be coerced into `{target_ty}`"
|
||||
),
|
||||
"&",
|
||||
Applicability::MaybeIncorrect,
|
||||
@ -2851,30 +2852,27 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
||||
err.span_note(tcx.def_span(item_def_id), descr);
|
||||
}
|
||||
}
|
||||
ObligationCauseCode::ObjectCastObligation(concrete_ty, object_ty) => {
|
||||
let (concrete_ty, concrete_file) =
|
||||
self.tcx.short_ty_string(self.resolve_vars_if_possible(concrete_ty));
|
||||
let (object_ty, object_file) =
|
||||
self.tcx.short_ty_string(self.resolve_vars_if_possible(object_ty));
|
||||
ObligationCauseCode::Coercion { source, target } => {
|
||||
let (source, source_file) =
|
||||
self.tcx.short_ty_string(self.resolve_vars_if_possible(source));
|
||||
let (target, target_file) =
|
||||
self.tcx.short_ty_string(self.resolve_vars_if_possible(target));
|
||||
err.note(with_forced_trimmed_paths!(format!(
|
||||
"required for the cast from `{concrete_ty}` to the object type `{object_ty}`",
|
||||
"required for the cast from `{source}` to `{target}`",
|
||||
)));
|
||||
if let Some(file) = concrete_file {
|
||||
if let Some(file) = source_file {
|
||||
err.note(format!(
|
||||
"the full name for the casted type has been written to '{}'",
|
||||
"the full name for the source type has been written to '{}'",
|
||||
file.display(),
|
||||
));
|
||||
}
|
||||
if let Some(file) = object_file {
|
||||
if let Some(file) = target_file {
|
||||
err.note(format!(
|
||||
"the full name for the object type has been written to '{}'",
|
||||
"the full name for the target type has been written to '{}'",
|
||||
file.display(),
|
||||
));
|
||||
}
|
||||
}
|
||||
ObligationCauseCode::Coercion { source: _, target } => {
|
||||
err.note(format!("required by cast to type `{}`", self.ty_to_string(target)));
|
||||
}
|
||||
ObligationCauseCode::RepeatElementCopy { is_const_fn } => {
|
||||
err.note(
|
||||
"the `Copy` trait is required because this value will be copied for each element of the array",
|
||||
|
@ -29,9 +29,9 @@ use crate::traits::{
|
||||
ImplSourceAutoImplData, ImplSourceBuiltinData, ImplSourceClosureData,
|
||||
ImplSourceConstDestructData, ImplSourceFnPointerData, ImplSourceFutureData,
|
||||
ImplSourceGeneratorData, ImplSourceObjectData, ImplSourceTraitAliasData,
|
||||
ImplSourceTraitUpcastingData, ImplSourceUserDefinedData, Normalized, ObjectCastObligation,
|
||||
Obligation, ObligationCause, OutputTypeParameterMismatch, PredicateObligation, Selection,
|
||||
SelectionError, TraitNotObjectSafe, TraitObligation, Unimplemented,
|
||||
ImplSourceTraitUpcastingData, ImplSourceUserDefinedData, Normalized, Obligation,
|
||||
ObligationCause, OutputTypeParameterMismatch, PredicateObligation, Selection, SelectionError,
|
||||
TraitNotObjectSafe, TraitObligation, Unimplemented,
|
||||
};
|
||||
|
||||
use super::BuiltinImplConditions;
|
||||
@ -905,16 +905,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
.map_err(|_| Unimplemented)?;
|
||||
nested.extend(obligations);
|
||||
|
||||
// Register one obligation for 'a: 'b.
|
||||
let cause = ObligationCause::new(
|
||||
obligation.cause.span,
|
||||
obligation.cause.body_id,
|
||||
ObjectCastObligation(source, target),
|
||||
);
|
||||
let outlives = ty::OutlivesPredicate(r_a, r_b);
|
||||
nested.push(Obligation::with_depth(
|
||||
tcx,
|
||||
cause,
|
||||
obligation.cause.clone(),
|
||||
obligation.recursion_depth + 1,
|
||||
obligation.param_env,
|
||||
obligation.predicate.rebind(outlives),
|
||||
@ -1005,15 +999,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
nested.extend(obligations);
|
||||
|
||||
// Register one obligation for 'a: 'b.
|
||||
let cause = ObligationCause::new(
|
||||
obligation.cause.span,
|
||||
obligation.cause.body_id,
|
||||
ObjectCastObligation(source, target),
|
||||
);
|
||||
let outlives = ty::OutlivesPredicate(r_a, r_b);
|
||||
nested.push(Obligation::with_depth(
|
||||
tcx,
|
||||
cause,
|
||||
obligation.cause.clone(),
|
||||
obligation.recursion_depth + 1,
|
||||
obligation.param_env,
|
||||
obligation.predicate.rebind(outlives),
|
||||
@ -1027,16 +1016,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
return Err(TraitNotObjectSafe(did));
|
||||
}
|
||||
|
||||
let cause = ObligationCause::new(
|
||||
obligation.cause.span,
|
||||
obligation.cause.body_id,
|
||||
ObjectCastObligation(source, target),
|
||||
);
|
||||
|
||||
let predicate_to_obligation = |predicate| {
|
||||
Obligation::with_depth(
|
||||
tcx,
|
||||
cause.clone(),
|
||||
obligation.cause.clone(),
|
||||
obligation.recursion_depth + 1,
|
||||
obligation.param_env,
|
||||
predicate,
|
||||
@ -1056,7 +1039,12 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
);
|
||||
|
||||
// We can only make objects from sized types.
|
||||
let tr = ty::TraitRef::from_lang_item(tcx, LangItem::Sized, cause.span, [source]);
|
||||
let tr = ty::TraitRef::from_lang_item(
|
||||
tcx,
|
||||
LangItem::Sized,
|
||||
obligation.cause.span,
|
||||
[source],
|
||||
);
|
||||
nested.push(predicate_to_obligation(tr.without_const().to_predicate(tcx)));
|
||||
|
||||
// If the type is `Foo + 'a`, ensure that the type
|
||||
|
@ -2647,14 +2647,19 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
|
||||
let predicates = predicates.instantiate_own(tcx, substs);
|
||||
let mut obligations = Vec::with_capacity(predicates.len());
|
||||
for (index, (predicate, span)) in predicates.into_iter().enumerate() {
|
||||
let cause = cause.clone().derived_cause(parent_trait_pred, |derived| {
|
||||
ImplDerivedObligation(Box::new(ImplDerivedObligationCause {
|
||||
derived,
|
||||
impl_or_alias_def_id: def_id,
|
||||
impl_def_predicate_index: Some(index),
|
||||
span,
|
||||
}))
|
||||
});
|
||||
let cause =
|
||||
if Some(parent_trait_pred.def_id()) == tcx.lang_items().coerce_unsized_trait() {
|
||||
cause.clone()
|
||||
} else {
|
||||
cause.clone().derived_cause(parent_trait_pred, |derived| {
|
||||
ImplDerivedObligation(Box::new(ImplDerivedObligationCause {
|
||||
derived,
|
||||
impl_or_alias_def_id: def_id,
|
||||
impl_def_predicate_index: Some(index),
|
||||
span,
|
||||
}))
|
||||
})
|
||||
};
|
||||
let predicate = normalize_with_depth_to(
|
||||
self,
|
||||
param_env,
|
||||
|
@ -55,3 +55,11 @@ ty_utils_multiple_array_fields_simd_type = monomorphising SIMD type `{$ty}` with
|
||||
ty_utils_oversized_simd_type = monomorphising SIMD type `{$ty}` of length greater than {$max_lanes}
|
||||
|
||||
ty_utils_non_primitive_simd_type = monomorphising SIMD type `{$ty}` with a non-primitive-scalar (integer/float/pointer) element type `{$e_ty}`
|
||||
|
||||
ty_utils_impl_trait_duplicate_arg = non-defining opaque type use in defining scope
|
||||
.label = generic argument `{$arg}` used twice
|
||||
.note = for this opaque type
|
||||
|
||||
ty_utils_impl_trait_not_param = non-defining opaque type use in defining scope
|
||||
.label = argument `{$arg}` is not a generic parameter
|
||||
.note = for this opaque type
|
||||
|
@ -1,7 +1,7 @@
|
||||
//! Errors emitted by ty_utils
|
||||
|
||||
use rustc_macros::{Diagnostic, Subdiagnostic};
|
||||
use rustc_middle::ty::Ty;
|
||||
use rustc_middle::ty::{GenericArg, Ty};
|
||||
use rustc_span::Span;
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
@ -100,3 +100,25 @@ pub struct NonPrimitiveSimdType<'tcx> {
|
||||
pub ty: Ty<'tcx>,
|
||||
pub e_ty: Ty<'tcx>,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(ty_utils_impl_trait_duplicate_arg)]
|
||||
pub struct DuplicateArg<'tcx> {
|
||||
pub arg: GenericArg<'tcx>,
|
||||
#[primary_span]
|
||||
#[label]
|
||||
pub span: Span,
|
||||
#[note]
|
||||
pub opaque_span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(ty_utils_impl_trait_not_param)]
|
||||
pub struct NotParam<'tcx> {
|
||||
pub arg: GenericArg<'tcx>,
|
||||
#[primary_span]
|
||||
#[label]
|
||||
pub span: Span,
|
||||
#[note]
|
||||
pub opaque_span: Span,
|
||||
}
|
||||
|
@ -33,6 +33,7 @@ pub mod instance;
|
||||
mod layout;
|
||||
mod layout_sanity_check;
|
||||
mod needs_drop;
|
||||
mod opaque_types;
|
||||
pub mod representability;
|
||||
mod structural_match;
|
||||
mod ty;
|
||||
@ -47,6 +48,7 @@ pub fn provide(providers: &mut Providers) {
|
||||
implied_bounds::provide(providers);
|
||||
layout::provide(providers);
|
||||
needs_drop::provide(providers);
|
||||
opaque_types::provide(providers);
|
||||
representability::provide(providers);
|
||||
ty::provide(providers);
|
||||
instance::provide(providers);
|
||||
|
197
compiler/rustc_ty_utils/src/opaque_types.rs
Normal file
197
compiler/rustc_ty_utils/src/opaque_types.rs
Normal file
@ -0,0 +1,197 @@
|
||||
use rustc_data_structures::fx::FxHashSet;
|
||||
use rustc_errors::ErrorGuaranteed;
|
||||
use rustc_hir::{def::DefKind, def_id::LocalDefId};
|
||||
use rustc_middle::ty::util::{CheckRegions, NotUniqueParam};
|
||||
use rustc_middle::ty::{self, Ty, TyCtxt};
|
||||
use rustc_middle::ty::{TypeSuperVisitable, TypeVisitable, TypeVisitor};
|
||||
use rustc_span::Span;
|
||||
use rustc_type_ir::AliasKind;
|
||||
use std::ops::ControlFlow;
|
||||
|
||||
use crate::errors::{DuplicateArg, NotParam};
|
||||
|
||||
struct OpaqueTypeCollector<'tcx> {
|
||||
tcx: TyCtxt<'tcx>,
|
||||
opaques: Vec<LocalDefId>,
|
||||
/// The `DefId` of the item which we are collecting opaque types for.
|
||||
item: LocalDefId,
|
||||
|
||||
/// Avoid infinite recursion due to recursive declarations.
|
||||
seen: FxHashSet<LocalDefId>,
|
||||
}
|
||||
|
||||
impl<'tcx> OpaqueTypeCollector<'tcx> {
|
||||
fn collect(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
item: LocalDefId,
|
||||
val: ty::Binder<'tcx, impl TypeVisitable<TyCtxt<'tcx>>>,
|
||||
) -> Vec<LocalDefId> {
|
||||
let mut collector = Self { tcx, opaques: Vec::new(), item, seen: Default::default() };
|
||||
val.skip_binder().visit_with(&mut collector);
|
||||
collector.opaques
|
||||
}
|
||||
|
||||
fn span(&self) -> Span {
|
||||
self.tcx.def_span(self.item)
|
||||
}
|
||||
|
||||
fn parent(&self) -> Option<LocalDefId> {
|
||||
match self.tcx.def_kind(self.item) {
|
||||
DefKind::Fn => None,
|
||||
DefKind::AssocFn | DefKind::AssocTy | DefKind::AssocConst => {
|
||||
Some(self.tcx.local_parent(self.item))
|
||||
}
|
||||
other => span_bug!(
|
||||
self.tcx.def_span(self.item),
|
||||
"unhandled item with opaque types: {other:?}"
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for OpaqueTypeCollector<'tcx> {
|
||||
type BreakTy = ErrorGuaranteed;
|
||||
|
||||
#[instrument(skip(self), ret, level = "trace")]
|
||||
fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<ErrorGuaranteed> {
|
||||
match t.kind() {
|
||||
ty::Alias(AliasKind::Opaque, alias_ty) if alias_ty.def_id.is_local() => {
|
||||
if !self.seen.insert(alias_ty.def_id.expect_local()) {
|
||||
return ControlFlow::Continue(());
|
||||
}
|
||||
match self.tcx.uses_unique_generic_params(alias_ty.substs, CheckRegions::Bound) {
|
||||
Ok(()) => {
|
||||
// FIXME: implement higher kinded lifetime bounds on nested opaque types. They are not
|
||||
// supported at all, so this is sound to do, but once we want to support them, you'll
|
||||
// start seeing the error below.
|
||||
|
||||
self.opaques.push(alias_ty.def_id.expect_local());
|
||||
|
||||
// Collect opaque types nested within the associated type bounds of this opaque type.
|
||||
for (pred, _span) in self
|
||||
.tcx
|
||||
.explicit_item_bounds(alias_ty.def_id)
|
||||
.subst_iter_copied(self.tcx, alias_ty.substs)
|
||||
{
|
||||
trace!(?pred);
|
||||
pred.visit_with(self)?;
|
||||
}
|
||||
|
||||
ControlFlow::Continue(())
|
||||
}
|
||||
Err(NotUniqueParam::NotParam(arg)) => {
|
||||
let err = self.tcx.sess.emit_err(NotParam {
|
||||
arg,
|
||||
span: self.span(),
|
||||
opaque_span: self.tcx.def_span(alias_ty.def_id),
|
||||
});
|
||||
ControlFlow::Break(err)
|
||||
}
|
||||
Err(NotUniqueParam::DuplicateParam(arg)) => {
|
||||
let err = self.tcx.sess.emit_err(DuplicateArg {
|
||||
arg,
|
||||
span: self.span(),
|
||||
opaque_span: self.tcx.def_span(alias_ty.def_id),
|
||||
});
|
||||
ControlFlow::Break(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
ty::Alias(AliasKind::Projection, alias_ty) => {
|
||||
if let Some(parent) = self.parent() {
|
||||
trace!(?alias_ty);
|
||||
let (trait_ref, own_substs) = alias_ty.trait_ref_and_own_substs(self.tcx);
|
||||
|
||||
trace!(?trait_ref, ?own_substs);
|
||||
// This avoids having to do normalization of `Self::AssocTy` by only
|
||||
// supporting the case of a method defining opaque types from assoc types
|
||||
// in the same impl block.
|
||||
if trait_ref.self_ty() == self.tcx.type_of(parent).subst_identity() {
|
||||
for assoc in self.tcx.associated_items(parent).in_definition_order() {
|
||||
trace!(?assoc);
|
||||
if assoc.trait_item_def_id == Some(alias_ty.def_id) {
|
||||
// We reconstruct the generic args of the associated type within the impl
|
||||
// from the impl's generics and the generic args passed to the type via the
|
||||
// projection.
|
||||
let substs = ty::InternalSubsts::identity_for_item(
|
||||
self.tcx,
|
||||
parent.to_def_id(),
|
||||
);
|
||||
trace!(?substs);
|
||||
let substs: Vec<_> =
|
||||
substs.iter().chain(own_substs.iter().copied()).collect();
|
||||
trace!(?substs);
|
||||
// Find opaque types in this associated type.
|
||||
return self
|
||||
.tcx
|
||||
.type_of(assoc.def_id)
|
||||
.subst(self.tcx, &substs)
|
||||
.visit_with(self);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
t.super_visit_with(self)
|
||||
}
|
||||
_ => t.super_visit_with(self),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn opaque_types_defined_by<'tcx>(tcx: TyCtxt<'tcx>, item: LocalDefId) -> &'tcx [LocalDefId] {
|
||||
let kind = tcx.def_kind(item);
|
||||
trace!(?kind);
|
||||
// FIXME(type_alias_impl_trait): This is definitely still wrong except for RPIT and impl trait in assoc types.
|
||||
match kind {
|
||||
// We're also doing this for `AssocTy` for the wf checks in `check_opaque_meets_bounds`
|
||||
DefKind::Fn | DefKind::AssocFn | DefKind::AssocTy | DefKind::AssocConst => {
|
||||
let defined_opaques = match kind {
|
||||
DefKind::Fn => {
|
||||
OpaqueTypeCollector::collect(tcx, item, tcx.fn_sig(item).subst_identity())
|
||||
}
|
||||
DefKind::AssocFn => {
|
||||
OpaqueTypeCollector::collect(tcx, item, tcx.fn_sig(item).subst_identity())
|
||||
}
|
||||
DefKind::AssocTy | DefKind::AssocConst => OpaqueTypeCollector::collect(
|
||||
tcx,
|
||||
item,
|
||||
ty::Binder::dummy(tcx.type_of(item).subst_identity()),
|
||||
),
|
||||
_ => unreachable!(),
|
||||
};
|
||||
tcx.arena.alloc_from_iter(defined_opaques)
|
||||
}
|
||||
DefKind::Mod
|
||||
| DefKind::Struct
|
||||
| DefKind::Union
|
||||
| DefKind::Enum
|
||||
| DefKind::Variant
|
||||
| DefKind::Trait
|
||||
| DefKind::TyAlias
|
||||
| DefKind::ForeignTy
|
||||
| DefKind::TraitAlias
|
||||
| DefKind::TyParam
|
||||
| DefKind::Const
|
||||
| DefKind::ConstParam
|
||||
| DefKind::Static(_)
|
||||
| DefKind::Ctor(_, _)
|
||||
| DefKind::Macro(_)
|
||||
| DefKind::ExternCrate
|
||||
| DefKind::Use
|
||||
| DefKind::ForeignMod
|
||||
| DefKind::AnonConst
|
||||
| DefKind::InlineConst
|
||||
| DefKind::OpaqueTy
|
||||
| DefKind::ImplTraitPlaceholder
|
||||
| DefKind::Field
|
||||
| DefKind::LifetimeParam
|
||||
| DefKind::GlobalAsm
|
||||
| DefKind::Impl { .. }
|
||||
| DefKind::Closure
|
||||
| DefKind::Generator => &[],
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn provide(providers: &mut ty::query::Providers) {
|
||||
*providers = ty::query::Providers { opaque_types_defined_by, ..*providers };
|
||||
}
|
@ -455,7 +455,8 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
|
||||
| hir::ItemKind::Union(..)
|
||||
| hir::ItemKind::TyAlias(..)
|
||||
| hir::ItemKind::OpaqueTy(hir::OpaqueTy {
|
||||
origin: hir::OpaqueTyOrigin::TyAlias, ..
|
||||
origin: hir::OpaqueTyOrigin::TyAlias { .. },
|
||||
..
|
||||
})
|
||||
| hir::ItemKind::Static(..)
|
||||
| hir::ItemKind::Trait(..)
|
||||
|
@ -36,7 +36,7 @@ CHECK-SAME: section "llvm.metadata"
|
||||
CHECK: [[DEFINE_INTERNAL]] { {{.*}} } @_R{{[a-zA-Z0-9_]+}}testprog14will_be_called() unnamed_addr #{{[0-9]+}} {
|
||||
CHECK-NEXT: start:
|
||||
CHECK-NOT: [[DEFINE_INTERNAL]]
|
||||
CHECK: %pgocount = load i64, {{i64\*|ptr}}
|
||||
CHECK: atomicrmw add ptr
|
||||
CHECK-SAME: @__profc__R{{[a-zA-Z0-9_]+}}testprog14will_be_called,
|
||||
|
||||
CHECK: declare void @llvm.instrprof.increment({{i8\*|ptr}}, i64, i32, i32) #[[LLVM_INSTRPROF_INCREMENT_ATTR:[0-9]+]]
|
||||
|
@ -43,7 +43,7 @@ note: expected this to be `Bar`
|
||||
|
|
||||
LL | type A = usize;
|
||||
| ^^^^^
|
||||
= note: required for the cast from `isize` to the object type `dyn Foo<A = Bar>`
|
||||
= note: required for the cast from `&isize` to `&dyn Foo<A = Bar>`
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
|
@ -4,7 +4,7 @@ error[E0271]: expected `IntoIter<u32>` to be an iterator that yields `i32`, but
|
||||
LL | let _: &dyn I32Iterator<Item = u32> = &vec![42].into_iter();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^ expected `i32`, found `u32`
|
||||
|
|
||||
= note: required for the cast from `std::vec::IntoIter<u32>` to the object type `dyn Iterator<Item = u32, Item = i32>`
|
||||
= note: required for the cast from `&std::vec::IntoIter<u32>` to `&dyn Iterator<Item = u32, Item = i32>`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -25,7 +25,7 @@ LL | impl<'a, T: MyDisplay> MyDisplay for &'a mut T { }
|
||||
| --------- ^^^^^^^^^ ^^^^^^^^^
|
||||
| |
|
||||
| unsatisfied trait bound introduced here
|
||||
= note: required for the cast from `&mut T` to the object type `dyn MyDisplay`
|
||||
= note: required for the cast from `&&mut T` to `&dyn MyDisplay`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
@ -18,7 +18,7 @@ LL | writer.my_write(valref)
|
||||
| ^^^^^^ the trait `MyDisplay` is not implemented for `T`
|
||||
|
|
||||
= help: the trait `MyDisplay` is implemented for `&'a mut T`
|
||||
= note: required for the cast from `T` to the object type `dyn MyDisplay`
|
||||
= note: required for the cast from `&mut T` to `&dyn MyDisplay`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
@ -35,7 +35,7 @@ error[E0271]: expected `[async block@$DIR/async-block-control-flow-static-semant
|
||||
LL | let _: &dyn Future<Output = ()> = █
|
||||
| ^^^^^^ expected `()`, found `u8`
|
||||
|
|
||||
= note: required for the cast from `[async block@$DIR/async-block-control-flow-static-semantics.rs:23:17: 25:6]` to the object type `dyn Future<Output = ()>`
|
||||
= note: required for the cast from `&[async block@$DIR/async-block-control-flow-static-semantics.rs:23:17: 25:6]` to `&dyn Future<Output = ()>`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/async-block-control-flow-static-semantics.rs:12:43
|
||||
@ -51,7 +51,7 @@ error[E0271]: expected `[async block@$DIR/async-block-control-flow-static-semant
|
||||
LL | let _: &dyn Future<Output = ()> = █
|
||||
| ^^^^^^ expected `()`, found `u8`
|
||||
|
|
||||
= note: required for the cast from `[async block@$DIR/async-block-control-flow-static-semantics.rs:14:17: 16:6]` to the object type `dyn Future<Output = ()>`
|
||||
= note: required for the cast from `&[async block@$DIR/async-block-control-flow-static-semantics.rs:14:17: 16:6]` to `&dyn Future<Output = ()>`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/async-block-control-flow-static-semantics.rs:49:44
|
||||
|
@ -13,7 +13,7 @@ note: captured value is not `Send` because `&` references cannot be sent unless
|
||||
|
|
||||
LL | let x = x;
|
||||
| ^ has type `&T` which is not `Send`, because `T` is not `Sync`
|
||||
= note: required for the cast from `[async block@$DIR/issue-86507.rs:21:17: 23:18]` to the object type `dyn Future<Output = ()> + Send`
|
||||
= note: required for the cast from `Pin<Box<[async block@$DIR/issue-86507.rs:21:17: 23:18]>>` to `Pin<Box<(dyn Future<Output = ()> + Send + 'async_trait)>>`
|
||||
help: consider further restricting this bound
|
||||
|
|
||||
LL | fn bar<'me, 'async_trait, T: Send + std::marker::Sync>(x: &'me T)
|
||||
|
@ -13,7 +13,7 @@ note: captured value is not `Send` because `&` references cannot be sent unless
|
||||
|
|
||||
LL | let x = x;
|
||||
| ^ has type `&T` which is not `Send`, because `T` is not `Sync`
|
||||
= note: required for the cast from `[async block@$DIR/issue-86507.rs:21:17: 23:18]` to the object type `dyn Future<Output = ()> + Send`
|
||||
= note: required for the cast from `Pin<Box<[async block@$DIR/issue-86507.rs:21:17: 23:18]>>` to `Pin<Box<(dyn Future<Output = ()> + Send + 'async_trait)>>`
|
||||
help: consider further restricting this bound
|
||||
|
|
||||
LL | fn bar<'me, 'async_trait, T: Send + std::marker::Sync>(x: &'me T)
|
||||
|
@ -13,7 +13,7 @@ note: captured value is not `Send` because `&` references cannot be sent unless
|
||||
|
|
||||
LL | let x = x;
|
||||
| ^ has type `&T` which is not `Send`, because `T` is not `Sync`
|
||||
= note: required for the cast from `[async block@$DIR/issue-86507.rs:21:17: 23:18]` to the object type `dyn Future<Output = ()> + Send`
|
||||
= note: required for the cast from `Pin<Box<[async block@$DIR/issue-86507.rs:21:17: 23:18]>>` to `Pin<Box<(dyn Future<Output = ()> + Send + 'async_trait)>>`
|
||||
help: consider further restricting this bound
|
||||
|
|
||||
LL | fn bar<'me, 'async_trait, T: Send + std::marker::Sync>(x: &'me T)
|
||||
|
@ -9,7 +9,7 @@ LL | num += 1;
|
||||
LL | Box::new(closure)
|
||||
| ----------------- the requirement to implement `Fn` derives from here
|
||||
|
|
||||
= note: required for the cast from `[closure@$DIR/issue-26046-fn-mut.rs:4:19: 4:21]` to the object type `dyn Fn()`
|
||||
= note: required for the cast from `Box<[closure@$DIR/issue-26046-fn-mut.rs:4:19: 4:21]>` to `Box<(dyn Fn() + 'static)>`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -9,7 +9,7 @@ LL | vec
|
||||
LL | Box::new(closure)
|
||||
| ----------------- the requirement to implement `Fn` derives from here
|
||||
|
|
||||
= note: required for the cast from `[closure@$DIR/issue-26046-fn-once.rs:4:19: 4:26]` to the object type `dyn Fn() -> Vec<u8>`
|
||||
= note: required for the cast from `Box<[closure@$DIR/issue-26046-fn-once.rs:4:19: 4:26]>` to `Box<(dyn Fn() -> Vec<u8> + 'static)>`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -4,7 +4,7 @@ error[E0277]: the trait bound `(): std::error::Error` is not satisfied
|
||||
LL | /* *mut $0 is coerced to Box<dyn Error> here */ Box::<_ /* ! */>::new(x)
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::error::Error` is not implemented for `()`
|
||||
|
|
||||
= note: required for the cast from `()` to the object type `dyn std::error::Error`
|
||||
= note: required for the cast from `Box<()>` to `Box<(dyn std::error::Error + 'static)>`
|
||||
|
||||
error[E0277]: the trait bound `(): std::error::Error` is not satisfied
|
||||
--> $DIR/coerce-issue-49593-box-never-windows.rs:23:49
|
||||
@ -12,7 +12,7 @@ error[E0277]: the trait bound `(): std::error::Error` is not satisfied
|
||||
LL | /* *mut $0 is coerced to *mut Error here */ raw_ptr_box::<_ /* ! */>(x)
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::error::Error` is not implemented for `()`
|
||||
|
|
||||
= note: required for the cast from `()` to the object type `(dyn std::error::Error + 'static)`
|
||||
= note: required for the cast from `*mut ()` to `*mut (dyn std::error::Error + 'static)`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
@ -4,7 +4,7 @@ error[E0277]: the trait bound `(): std::error::Error` is not satisfied
|
||||
LL | /* *mut $0 is coerced to Box<dyn Error> here */ Box::<_ /* ! */>::new(x)
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::error::Error` is not implemented for `()`
|
||||
|
|
||||
= note: required for the cast from `()` to the object type `dyn std::error::Error`
|
||||
= note: required for the cast from `Box<()>` to `Box<(dyn std::error::Error + 'static)>`
|
||||
|
||||
error[E0277]: the trait bound `(): std::error::Error` is not satisfied
|
||||
--> $DIR/coerce-issue-49593-box-never.rs:23:49
|
||||
@ -12,7 +12,7 @@ error[E0277]: the trait bound `(): std::error::Error` is not satisfied
|
||||
LL | /* *mut $0 is coerced to *mut Error here */ raw_ptr_box::<_ /* ! */>(x)
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::error::Error` is not implemented for `()`
|
||||
|
|
||||
= note: required for the cast from `()` to the object type `(dyn std::error::Error + 'static)`
|
||||
= note: required for the cast from `*mut ()` to `*mut (dyn std::error::Error + 'static)`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
@ -5,7 +5,7 @@ LL | foo(&10_u32);
|
||||
| ^^^^^^^ the trait `Trait` is not implemented for `u32`
|
||||
|
|
||||
= help: the trait `Trait<2>` is implemented for `u32`
|
||||
= note: required for the cast from `u32` to the object type `dyn Trait`
|
||||
= note: required for the cast from `&u32` to `&dyn Trait`
|
||||
|
||||
error[E0277]: the trait bound `bool: Traitor<_>` is not satisfied
|
||||
--> $DIR/trait_objects_fail.rs:28:9
|
||||
@ -14,7 +14,7 @@ LL | bar(&true);
|
||||
| ^^^^^ the trait `Traitor<_>` is not implemented for `bool`
|
||||
|
|
||||
= help: the trait `Traitor<2, 3>` is implemented for `bool`
|
||||
= note: required for the cast from `bool` to the object type `dyn Traitor<_>`
|
||||
= note: required for the cast from `&bool` to `&dyn Traitor<_>`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
@ -6,7 +6,7 @@ LL | #[test]
|
||||
LL | fn wrong_kind(){}
|
||||
| ^^^^^^^^^^^^^^^^^ the trait `Testable` is not implemented for `TestDescAndFn`
|
||||
|
|
||||
= note: required for the cast from `TestDescAndFn` to the object type `dyn Testable`
|
||||
= note: required for the cast from `&TestDescAndFn` to `&dyn Testable`
|
||||
= note: this error originates in the attribute macro `test` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: aborting due to previous error
|
||||
|
@ -15,8 +15,8 @@ note: expected this to be `Foo`
|
||||
|
|
||||
LL | type Error = E;
|
||||
| ^
|
||||
= note: required for the cast from `Result<Result<..., ...>, ...>` to the object type `dyn Future<Error = Foo>`
|
||||
= note: the full name for the casted type has been written to '$TEST_BUILD_DIR/diagnostic-width/E0271/E0271.long-type-hash.txt'
|
||||
= note: required for the cast from `Box<Result<..., ...>>` to `Box<(dyn Future<Error = Foo> + 'static)>`
|
||||
= note: the full name for the source type has been written to '$TEST_BUILD_DIR/diagnostic-width/E0271/E0271.long-type-hash.txt'
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -15,7 +15,7 @@ error[E0277]: the trait bound `Foo: Bar` is not satisfied
|
||||
LL | let f3: &Fat<dyn Bar> = f2;
|
||||
| ^^ the trait `Bar` is not implemented for `Foo`
|
||||
|
|
||||
= note: required for the cast from `Foo` to the object type `dyn Bar`
|
||||
= note: required for the cast from `&Fat<Foo>` to `&Fat<dyn Bar>`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/dst-bad-coerce1.rs:28:27
|
||||
@ -34,7 +34,7 @@ error[E0277]: the trait bound `Foo: Bar` is not satisfied
|
||||
LL | let f3: &(dyn Bar,) = f2;
|
||||
| ^^ the trait `Bar` is not implemented for `Foo`
|
||||
|
|
||||
= note: required for the cast from `Foo` to the object type `dyn Bar`
|
||||
= note: required for the cast from `&(Foo,)` to `&(dyn Bar,)`
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
|
@ -6,7 +6,7 @@ LL | fn test1<T: ?Sized + Foo>(t: &T) {
|
||||
LL | let u: &dyn Foo = t;
|
||||
| ^ doesn't have a size known at compile-time
|
||||
|
|
||||
= note: required for the cast from `T` to the object type `dyn Foo`
|
||||
= note: required for the cast from `&T` to `&dyn Foo`
|
||||
help: consider removing the `?Sized` bound to make the type parameter `Sized`
|
||||
|
|
||||
LL - fn test1<T: ?Sized + Foo>(t: &T) {
|
||||
@ -21,7 +21,7 @@ LL | fn test2<T: ?Sized + Foo>(t: &T) {
|
||||
LL | let v: &dyn Foo = t as &dyn Foo;
|
||||
| ^ doesn't have a size known at compile-time
|
||||
|
|
||||
= note: required for the cast from `T` to the object type `dyn Foo`
|
||||
= note: required for the cast from `&T` to `&dyn Foo`
|
||||
help: consider removing the `?Sized` bound to make the type parameter `Sized`
|
||||
|
|
||||
LL - fn test2<T: ?Sized + Foo>(t: &T) {
|
||||
@ -35,7 +35,7 @@ LL | let _: &[&dyn Foo] = &["hi"];
|
||||
| ^^^^ doesn't have a size known at compile-time
|
||||
|
|
||||
= help: the trait `Sized` is not implemented for `str`
|
||||
= note: required for the cast from `str` to the object type `dyn Foo`
|
||||
= note: required for the cast from `&'static str` to `&dyn Foo`
|
||||
|
||||
error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
|
||||
--> $DIR/dst-object-from-unsized-type.rs:23:23
|
||||
@ -44,7 +44,7 @@ LL | let _: &dyn Foo = x as &dyn Foo;
|
||||
| ^ doesn't have a size known at compile-time
|
||||
|
|
||||
= help: the trait `Sized` is not implemented for `[u8]`
|
||||
= note: required for the cast from `[u8]` to the object type `dyn Foo`
|
||||
= note: required for the cast from `&[u8]` to `&dyn Foo`
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
|
@ -0,0 +1,7 @@
|
||||
#[derive(Default)]
|
||||
pub enum Foo {
|
||||
A(u32),
|
||||
#[default]
|
||||
B,
|
||||
C(u32),
|
||||
}
|
11
tests/ui/enum-discriminant/discr-foreign.rs
Normal file
11
tests/ui/enum-discriminant/discr-foreign.rs
Normal file
@ -0,0 +1,11 @@
|
||||
// aux-build:discr-foreign-dep.rs
|
||||
// build-pass
|
||||
|
||||
extern crate discr_foreign_dep;
|
||||
|
||||
fn main() {
|
||||
match Default::default() {
|
||||
discr_foreign_dep::Foo::A(_) => {}
|
||||
_ => {}
|
||||
}
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
#![crate_type = "lib"]
|
||||
|
||||
#[cfg(overflow_checks)] //~ ERROR `cfg(overflow_checks)` is experimental
|
||||
pub fn cast(v: i64)->u32{
|
||||
todo!()
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
error[E0658]: `cfg(overflow_checks)` is experimental and subject to change
|
||||
--> $DIR/feature-gate-cfg_overflow_checks.rs:3:7
|
||||
|
|
||||
LL | #[cfg(overflow_checks)]
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #111466 <https://github.com/rust-lang/rust/issues/111466> for more information
|
||||
= help: add `#![feature(cfg_overflow_checks)]` to the crate attributes to enable
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0658`.
|
@ -31,14 +31,7 @@ LL | trait Trait {
|
||||
| ----- this trait cannot be made into an object...
|
||||
LL | fn ptr(self: Ptr<Self>);
|
||||
| ^^^^^^^^^ ...because method `ptr`'s `self` parameter cannot be dispatched on
|
||||
note: required for `Ptr<{integer}>` to implement `CoerceUnsized<Ptr<dyn Trait>>`
|
||||
--> $DIR/feature-gate-dispatch-from-dyn-missing-impl.rs:20:40
|
||||
|
|
||||
LL | impl<T: Unsize<U> + ?Sized, U: ?Sized> CoerceUnsized<Ptr<U>> for Ptr<T> {}
|
||||
| --------- ^^^^^^^^^^^^^^^^^^^^^ ^^^^^^
|
||||
| |
|
||||
| unsatisfied trait bound introduced here
|
||||
= note: required by cast to type `Ptr<dyn Trait>`
|
||||
= note: required for the cast from `Ptr<{integer}>` to `Ptr<dyn Trait>`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
@ -43,8 +43,7 @@ LL | pub trait SuperTrait {
|
||||
LL | type SubType<'a>: SubTrait where Self: 'a;
|
||||
| ^^^^^^^ ...because it contains the generic associated type `SubType`
|
||||
= help: consider moving `SubType` to another trait
|
||||
= note: required for `Box<SuperStruct>` to implement `CoerceUnsized<Box<dyn SuperTrait<SubType = SubStruct<'_>>>>`
|
||||
= note: required by cast to type `Box<dyn SuperTrait<SubType = SubStruct<'_>>>`
|
||||
= note: required for the cast from `Box<SuperStruct>` to `Box<dyn SuperTrait<SubType = SubStruct<'_>>>`
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
|
@ -43,8 +43,7 @@ LL | trait MapLike<K, V> {
|
||||
LL | type VRefCont<'a>: RefCont<'a, V> where Self: 'a;
|
||||
| ^^^^^^^^ ...because it contains the generic associated type `VRefCont`
|
||||
= help: consider moving `VRefCont` to another trait
|
||||
= note: required for `Box<BTreeMap<u8, u8>>` to implement `CoerceUnsized<Box<dyn MapLike<u8, u8, VRefCont = (dyn RefCont<'_, u8> + 'static)>>>`
|
||||
= note: required by cast to type `Box<dyn MapLike<u8, u8, VRefCont = (dyn RefCont<'_, u8> + 'static)>>`
|
||||
= note: required for the cast from `Box<BTreeMap<u8, u8>>` to `Box<dyn MapLike<u8, u8, VRefCont = (dyn RefCont<'_, u8> + 'static)>>`
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
|
@ -27,7 +27,7 @@ LL | type VRefCont<'a> = &'a V where Self: 'a;
|
||||
| ^^^^^
|
||||
= note: expected trait object `(dyn RefCont<'_, u8> + 'static)`
|
||||
found reference `&u8`
|
||||
= note: required for the cast from `BTreeMap<u8, u8>` to the object type `dyn MapLike<u8, u8, VRefCont = (dyn RefCont<'_, u8> + 'static)>`
|
||||
= note: required for the cast from `Box<BTreeMap<u8, u8>>` to `Box<dyn MapLike<u8, u8, VRefCont = (dyn RefCont<'_, u8> + 'static)>>`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
@ -19,4 +19,5 @@ impl<'a> A<'a> for C {
|
||||
type B<'b> = impl Clone;
|
||||
|
||||
fn a(&'a self) -> Self::B<'a> {} //~ ERROR: non-defining opaque type use in defining scope
|
||||
//~^ ERROR: mismatched types
|
||||
}
|
||||
|
@ -1,16 +1,34 @@
|
||||
error: non-defining opaque type use in defining scope
|
||||
--> $DIR/issue-88595.rs:21:35
|
||||
--> $DIR/issue-88595.rs:21:5
|
||||
|
|
||||
LL | fn a(&'a self) -> Self::B<'a> {}
|
||||
| ^^
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ generic argument `'a` used twice
|
||||
|
|
||||
note: lifetime used multiple times
|
||||
--> $DIR/issue-88595.rs:18:6
|
||||
note: for this opaque type
|
||||
--> $DIR/issue-88595.rs:19:18
|
||||
|
|
||||
LL | impl<'a> A<'a> for C {
|
||||
| ^^
|
||||
LL | type B<'b> = impl Clone;
|
||||
| ^^
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error: aborting due to previous error
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/issue-88595.rs:21:23
|
||||
|
|
||||
LL | type B<'b> = impl Clone;
|
||||
| ---------- the expected opaque type
|
||||
LL |
|
||||
LL | fn a(&'a self) -> Self::B<'a> {}
|
||||
| - ^^^^^^^^^^^ expected opaque type, found `()`
|
||||
| |
|
||||
| implicitly returns `()` as its body has no tail or `return` expression
|
||||
|
|
||||
= note: expected opaque type `<C as A<'a>>::B<'a>`
|
||||
found unit type `()`
|
||||
note: this item must have the opaque type in its signature in order to be able to register hidden types
|
||||
--> $DIR/issue-88595.rs:21:5
|
||||
|
|
||||
LL | fn a(&'a self) -> Self::B<'a> {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0308`.
|
||||
|
27
tests/ui/impl-trait/in-assoc-type-unconstrained.rs
Normal file
27
tests/ui/impl-trait/in-assoc-type-unconstrained.rs
Normal file
@ -0,0 +1,27 @@
|
||||
#![feature(impl_trait_in_assoc_type)]
|
||||
|
||||
mod compare_ty {
|
||||
trait Trait {
|
||||
type Ty: IntoIterator<Item = ()>;
|
||||
}
|
||||
impl Trait for () {
|
||||
type Ty = Option<impl Sized>;
|
||||
//~^ ERROR: unconstrained opaque type
|
||||
//~| ERROR: type mismatch resolving `<Option<<() as Trait>::Ty::{opaque#0}> as IntoIterator>::Item == ()`
|
||||
}
|
||||
}
|
||||
|
||||
mod compare_method {
|
||||
trait Trait {
|
||||
type Ty;
|
||||
fn method() -> Self::Ty;
|
||||
}
|
||||
impl Trait for () {
|
||||
type Ty = impl Sized;
|
||||
//~^ ERROR: unconstrained opaque type
|
||||
fn method() -> () {}
|
||||
//~^ ERROR: method `method` has an incompatible type for trait
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
59
tests/ui/impl-trait/in-assoc-type-unconstrained.stderr
Normal file
59
tests/ui/impl-trait/in-assoc-type-unconstrained.stderr
Normal file
@ -0,0 +1,59 @@
|
||||
error[E0271]: type mismatch resolving `<Option<<() as Trait>::Ty::{opaque#0}> as IntoIterator>::Item == ()`
|
||||
--> $DIR/in-assoc-type-unconstrained.rs:8:19
|
||||
|
|
||||
LL | type Ty = Option<impl Sized>;
|
||||
| ^^^^^^^^^^^^^^^^^^ expected `()`, found opaque type
|
||||
|
|
||||
= note: expected unit type `()`
|
||||
found opaque type `<() as compare_ty::Trait>::Ty::{opaque#0}`
|
||||
note: required by a bound in `compare_ty::Trait::Ty`
|
||||
--> $DIR/in-assoc-type-unconstrained.rs:5:31
|
||||
|
|
||||
LL | type Ty: IntoIterator<Item = ()>;
|
||||
| ^^^^^^^^^ required by this bound in `Trait::Ty`
|
||||
|
||||
error: unconstrained opaque type
|
||||
--> $DIR/in-assoc-type-unconstrained.rs:8:26
|
||||
|
|
||||
LL | type Ty = Option<impl Sized>;
|
||||
| ^^^^^^^^^^
|
||||
|
|
||||
= note: `Ty` must be used in combination with a concrete type within the same impl
|
||||
|
||||
error[E0053]: method `method` has an incompatible type for trait
|
||||
--> $DIR/in-assoc-type-unconstrained.rs:22:24
|
||||
|
|
||||
LL | type Ty = impl Sized;
|
||||
| ---------- the expected opaque type
|
||||
LL |
|
||||
LL | fn method() -> () {}
|
||||
| ^^
|
||||
| |
|
||||
| expected opaque type, found `()`
|
||||
| help: change the output type to match the trait: `<() as compare_method::Trait>::Ty`
|
||||
|
|
||||
note: type in trait
|
||||
--> $DIR/in-assoc-type-unconstrained.rs:17:24
|
||||
|
|
||||
LL | fn method() -> Self::Ty;
|
||||
| ^^^^^^^^
|
||||
= note: expected signature `fn() -> <() as compare_method::Trait>::Ty`
|
||||
found signature `fn()`
|
||||
note: this item must have the opaque type in its signature in order to be able to register hidden types
|
||||
--> $DIR/in-assoc-type-unconstrained.rs:22:9
|
||||
|
|
||||
LL | fn method() -> () {}
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: unconstrained opaque type
|
||||
--> $DIR/in-assoc-type-unconstrained.rs:20:19
|
||||
|
|
||||
LL | type Ty = impl Sized;
|
||||
| ^^^^^^^^^^
|
||||
|
|
||||
= note: `Ty` must be used in combination with a concrete type within the same impl
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0053, E0271.
|
||||
For more information about an error, try `rustc --explain E0053`.
|
21
tests/ui/impl-trait/in-assoc-type.rs
Normal file
21
tests/ui/impl-trait/in-assoc-type.rs
Normal file
@ -0,0 +1,21 @@
|
||||
#![feature(impl_trait_in_assoc_type)]
|
||||
|
||||
trait Foo<T> {
|
||||
type Bar;
|
||||
fn foo(&self) -> <Self as Foo<()>>::Bar
|
||||
where
|
||||
Self: Foo<()>;
|
||||
}
|
||||
|
||||
impl Foo<()> for () {
|
||||
type Bar = impl std::fmt::Debug;
|
||||
fn foo(&self) -> Self::Bar {}
|
||||
}
|
||||
|
||||
impl Foo<i32> for () {
|
||||
type Bar = u32;
|
||||
fn foo(&self) -> <Self as Foo<()>>::Bar {}
|
||||
//~^ ERROR: mismatched types
|
||||
}
|
||||
|
||||
fn main() {}
|
22
tests/ui/impl-trait/in-assoc-type.stderr
Normal file
22
tests/ui/impl-trait/in-assoc-type.stderr
Normal file
@ -0,0 +1,22 @@
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/in-assoc-type.rs:17:22
|
||||
|
|
||||
LL | type Bar = impl std::fmt::Debug;
|
||||
| -------------------- the expected opaque type
|
||||
...
|
||||
LL | fn foo(&self) -> <Self as Foo<()>>::Bar {}
|
||||
| --- ^^^^^^^^^^^^^^^^^^^^^^ expected opaque type, found `()`
|
||||
| |
|
||||
| implicitly returns `()` as its body has no tail or `return` expression
|
||||
|
|
||||
= note: expected opaque type `<() as Foo<()>>::Bar`
|
||||
found unit type `()`
|
||||
note: this item must have the opaque type in its signature in order to be able to register hidden types
|
||||
--> $DIR/in-assoc-type.rs:17:5
|
||||
|
|
||||
LL | fn foo(&self) -> <Self as Foo<()>>::Bar {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0308`.
|
@ -42,8 +42,7 @@ LL | trait Foo {
|
||||
LL | fn baz(&self) -> impl Debug;
|
||||
| ^^^^^^^^^^ ...because method `baz` references an `impl Trait` type in its return type
|
||||
= help: consider moving `baz` to another trait
|
||||
= note: required for `Box<u32>` to implement `CoerceUnsized<Box<dyn Foo>>`
|
||||
= note: required by cast to type `Box<dyn Foo>`
|
||||
= note: required for the cast from `Box<u32>` to `Box<dyn Foo>`
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
|
@ -42,8 +42,7 @@ LL | trait Foo {
|
||||
LL | fn baz(&self) -> impl Debug;
|
||||
| ^^^^^^^^^^ ...because method `baz` references an `impl Trait` type in its return type
|
||||
= help: consider moving `baz` to another trait
|
||||
= note: required for `Box<u32>` to implement `CoerceUnsized<Box<dyn Foo>>`
|
||||
= note: required by cast to type `Box<dyn Foo>`
|
||||
= note: required for the cast from `Box<u32>` to `Box<dyn Foo>`
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
|
@ -43,6 +43,11 @@ LL | fn eq(&self, _other: &(Bar, i32)) -> bool {
|
||||
|
|
||||
= note: expected signature `fn(&b::Bar, &(b::Foo, i32)) -> _`
|
||||
found signature `fn(&b::Bar, &(b::Bar, i32)) -> _`
|
||||
note: this item must have the opaque type in its signature in order to be able to register hidden types
|
||||
--> $DIR/recursive-type-alias-impl-trait-declaration-too-subtle.rs:24:9
|
||||
|
|
||||
LL | fn eq(&self, _other: &(Bar, i32)) -> bool {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
|
@ -5,8 +5,8 @@ LL | let _x = "test" as &dyn (::std::any::Any);
|
||||
| ^^^^^^ doesn't have a size known at compile-time
|
||||
|
|
||||
= help: the trait `Sized` is not implemented for `str`
|
||||
= note: required for the cast from `str` to the object type `dyn Any`
|
||||
help: consider borrowing the value, since `&str` can be coerced into `dyn Any`
|
||||
= note: required for the cast from `&'static str` to `&(dyn Any + 'static)`
|
||||
help: consider borrowing the value, since `&&'static str` can be coerced into `&(dyn Any + 'static)`
|
||||
|
|
||||
LL | let _x = &"test" as &dyn (::std::any::Any);
|
||||
| +
|
||||
|
@ -6,7 +6,7 @@ LL | &mut *(ptr as *mut dyn Fn())
|
||||
|
|
||||
= help: the trait `Fn<()>` is not implemented for `()`
|
||||
= note: wrap the `()` in a closure with no arguments: `|| { /* code */ }`
|
||||
= note: required for the cast from `()` to the object type `dyn Fn()`
|
||||
= note: required for the cast from `*mut ()` to `*mut dyn Fn()`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -13,7 +13,7 @@ LL | impl<'b, P> Wrap<'b> for Wrapper<P>
|
||||
LL | where P: Process<'b>,
|
||||
LL | <P as Process<'b>>::Item: Iterator {
|
||||
| -------- unsatisfied trait bound introduced here
|
||||
= note: required for the cast from `Wrapper<P>` to the object type `dyn for<'b> Wrap<'b>`
|
||||
= note: required for the cast from `Box<Wrapper<P>>` to `Box<dyn for<'b> Wrap<'b>>`
|
||||
help: consider further restricting the associated type
|
||||
|
|
||||
LL | fn push_process<P>(process: P) where P: Process<'static>, <P as Process<'_>>::Item: Iterator {
|
||||
|
@ -11,7 +11,7 @@ LL | impl<T: Send + Copy + 'static> Gettable<T> for S<T> {}
|
||||
| ---- ^^^^^^^^^^^ ^^^^
|
||||
| |
|
||||
| unsatisfied trait bound introduced here
|
||||
= note: required for the cast from `S<T>` to the object type `dyn Gettable<T>`
|
||||
= note: required for the cast from `&S<T>` to `&dyn Gettable<T>`
|
||||
help: consider restricting type parameter `T`
|
||||
|
|
||||
LL | fn f<T: std::marker::Send>(val: T) {
|
||||
@ -30,7 +30,7 @@ LL | impl<T: Send + Copy + 'static> Gettable<T> for S<T> {}
|
||||
| ---- ^^^^^^^^^^^ ^^^^
|
||||
| |
|
||||
| unsatisfied trait bound introduced here
|
||||
= note: required for the cast from `S<T>` to the object type `dyn Gettable<T>`
|
||||
= note: required for the cast from `&S<T>` to `&dyn Gettable<T>`
|
||||
help: consider restricting type parameter `T`
|
||||
|
|
||||
LL | fn f<T: std::marker::Copy>(val: T) {
|
||||
@ -49,7 +49,7 @@ LL | impl<T: Send + Copy + 'static> Gettable<T> for S<T> {}
|
||||
| ---- ^^^^^^^^^^^ ^^^^
|
||||
| |
|
||||
| unsatisfied trait bound introduced here
|
||||
= note: required for the cast from `S<T>` to the object type `dyn Gettable<T>`
|
||||
= note: required for the cast from `&S<T>` to `&dyn Gettable<T>`
|
||||
help: consider restricting type parameter `T`
|
||||
|
|
||||
LL | fn g<T: std::marker::Send>(val: T) {
|
||||
@ -68,7 +68,7 @@ LL | impl<T: Send + Copy + 'static> Gettable<T> for S<T> {}
|
||||
| ---- ^^^^^^^^^^^ ^^^^
|
||||
| |
|
||||
| unsatisfied trait bound introduced here
|
||||
= note: required for the cast from `S<T>` to the object type `dyn Gettable<T>`
|
||||
= note: required for the cast from `&S<T>` to `&dyn Gettable<T>`
|
||||
help: consider restricting type parameter `T`
|
||||
|
|
||||
LL | fn g<T: std::marker::Copy>(val: T) {
|
||||
@ -88,7 +88,7 @@ LL | impl<T: Send + Copy + 'static> Gettable<T> for S<T> {}
|
||||
| ---- ^^^^^^^^^^^ ^^^^
|
||||
| |
|
||||
| unsatisfied trait bound introduced here
|
||||
= note: required for the cast from `S<String>` to the object type `dyn Gettable<String>`
|
||||
= note: required for the cast from `Box<S<String>>` to `Box<dyn Gettable<String>>`
|
||||
|
||||
error[E0277]: the trait bound `Foo: Copy` is not satisfied
|
||||
--> $DIR/kindck-impl-type-params.rs:43:37
|
||||
@ -104,7 +104,7 @@ LL | impl<T: Send + Copy + 'static> Gettable<T> for S<T> {}
|
||||
| ---- ^^^^^^^^^^^ ^^^^
|
||||
| |
|
||||
| unsatisfied trait bound introduced here
|
||||
= note: required for the cast from `S<Foo>` to the object type `dyn Gettable<Foo>`
|
||||
= note: required for the cast from `Box<S<Foo>>` to `Box<dyn Gettable<Foo>>`
|
||||
help: consider annotating `Foo` with `#[derive(Copy)]`
|
||||
|
|
||||
LL + #[derive(Copy)]
|
||||
|
@ -46,8 +46,7 @@ LL | trait Foo : Copy {
|
||||
| --- ^^^^ ...because it requires `Self: Sized`
|
||||
| |
|
||||
| this trait cannot be made into an object...
|
||||
= note: required for `&Box<{integer}>` to implement `CoerceUnsized<&dyn Foo>`
|
||||
= note: required by cast to type `&dyn Foo`
|
||||
= note: required for the cast from `&Box<{integer}>` to `&dyn Foo`
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
|
@ -32,8 +32,7 @@ LL | trait Foo : Copy {
|
||||
| --- ^^^^ ...because it requires `Self: Sized`
|
||||
| |
|
||||
| this trait cannot be made into an object...
|
||||
= note: required for `&Box<i32>` to implement `CoerceUnsized<&dyn Foo>`
|
||||
= note: required by cast to type `&dyn Foo`
|
||||
= note: required for the cast from `&Box<i32>` to `&dyn Foo`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
@ -220,11 +220,7 @@ LL | let _ = fat_v as *const dyn Foo;
|
||||
| ^^^^^ doesn't have a size known at compile-time
|
||||
|
|
||||
= help: the trait `Sized` is not implemented for `[u8]`
|
||||
= note: required for the cast from `[u8]` to the object type `dyn Foo`
|
||||
help: consider borrowing the value, since `&[u8]` can be coerced into `dyn Foo`
|
||||
|
|
||||
LL | let _ = &fat_v as *const dyn Foo;
|
||||
| +
|
||||
= note: required for the cast from `*const [u8]` to `*const dyn Foo`
|
||||
|
||||
error[E0277]: the size for values of type `str` cannot be known at compilation time
|
||||
--> $DIR/cast-rfc0401.rs:62:13
|
||||
@ -233,11 +229,7 @@ LL | let _ = a as *const dyn Foo;
|
||||
| ^ doesn't have a size known at compile-time
|
||||
|
|
||||
= help: the trait `Sized` is not implemented for `str`
|
||||
= note: required for the cast from `str` to the object type `dyn Foo`
|
||||
help: consider borrowing the value, since `&str` can be coerced into `dyn Foo`
|
||||
|
|
||||
LL | let _ = &a as *const dyn Foo;
|
||||
| +
|
||||
= note: required for the cast from `*const str` to `*const dyn Foo`
|
||||
|
||||
error[E0606]: casting `&{float}` as `f32` is invalid
|
||||
--> $DIR/cast-rfc0401.rs:71:30
|
||||
|
@ -10,7 +10,7 @@ LL | | }) as Box<dyn FnMut()>);
|
||||
|
|
||||
= note: expected unit type `()`
|
||||
found type `!`
|
||||
= note: required for the cast from `[closure@$DIR/fallback-closure-wrap.rs:18:40: 18:47]` to the object type `dyn FnMut()`
|
||||
= note: required for the cast from `Box<[closure@$DIR/fallback-closure-wrap.rs:18:40: 18:47]>` to `Box<dyn FnMut()>`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
19
tests/ui/numbers-arithmetic/overflow-attribute-works-1.rs
Normal file
19
tests/ui/numbers-arithmetic/overflow-attribute-works-1.rs
Normal file
@ -0,0 +1,19 @@
|
||||
// run-pass
|
||||
// compile-flags: -C overflow_checks=true
|
||||
|
||||
#![feature(cfg_overflow_checks)]
|
||||
|
||||
fn main() {
|
||||
assert!(cfg!(overflow_checks));
|
||||
assert!(compiles_differently());
|
||||
}
|
||||
|
||||
#[cfg(overflow_checks)]
|
||||
fn compiles_differently()->bool {
|
||||
true
|
||||
}
|
||||
|
||||
#[cfg(not(overflow_checks))]
|
||||
fn compiles_differently()->bool {
|
||||
false
|
||||
}
|
19
tests/ui/numbers-arithmetic/overflow-attribute-works-2.rs
Normal file
19
tests/ui/numbers-arithmetic/overflow-attribute-works-2.rs
Normal file
@ -0,0 +1,19 @@
|
||||
// run-pass
|
||||
// compile-flags: -C overflow_checks=false
|
||||
|
||||
#![feature(cfg_overflow_checks)]
|
||||
|
||||
fn main() {
|
||||
assert!(!cfg!(overflow_checks));
|
||||
assert!(!compiles_differently());
|
||||
}
|
||||
|
||||
#[cfg(overflow_checks)]
|
||||
fn compiles_differently()->bool {
|
||||
true
|
||||
}
|
||||
|
||||
#[cfg(not(overflow_checks))]
|
||||
fn compiles_differently()->bool {
|
||||
false
|
||||
}
|
@ -29,8 +29,7 @@ LL | fn foo<T>(&self, val: T);
|
||||
LL | trait Bar: Foo { }
|
||||
| --- this trait cannot be made into an object...
|
||||
= help: consider moving `foo` to another trait
|
||||
= note: required for `&mut Thing` to implement `CoerceUnsized<&mut dyn Bar>`
|
||||
= note: required by cast to type `&mut dyn Bar`
|
||||
= note: required for the cast from `&mut Thing` to `&mut dyn Bar`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
@ -12,8 +12,7 @@ LL | trait Bar {
|
||||
LL | const X: usize;
|
||||
| ^ ...because it contains this associated `const`
|
||||
= help: consider moving `X` to another trait
|
||||
= note: required for `&T` to implement `CoerceUnsized<&dyn Bar>`
|
||||
= note: required by cast to type `&dyn Bar`
|
||||
= note: required for the cast from `&T` to `&dyn Bar`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -12,8 +12,7 @@ LL | trait Bar {
|
||||
LL | fn bar<T>(&self, t: T);
|
||||
| ^^^ ...because method `bar` has generic type parameters
|
||||
= help: consider moving `bar` to another trait
|
||||
= note: required for `&T` to implement `CoerceUnsized<&dyn Bar>`
|
||||
= note: required by cast to type `&dyn Bar`
|
||||
= note: required for the cast from `&T` to `&dyn Bar`
|
||||
|
||||
error[E0038]: the trait `Bar` cannot be made into an object
|
||||
--> $DIR/object-safety-generics.rs:26:5
|
||||
@ -29,8 +28,7 @@ LL | trait Bar {
|
||||
LL | fn bar<T>(&self, t: T);
|
||||
| ^^^ ...because method `bar` has generic type parameters
|
||||
= help: consider moving `bar` to another trait
|
||||
= note: required for `&T` to implement `CoerceUnsized<&dyn Bar>`
|
||||
= note: required by cast to type `&dyn Bar`
|
||||
= note: required for the cast from `&T` to `&dyn Bar`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
@ -12,8 +12,7 @@ LL | trait Bar {
|
||||
LL | fn bar(&self, x: &Self);
|
||||
| ^^^^^ ...because method `bar` references the `Self` type in this parameter
|
||||
= help: consider moving `bar` to another trait
|
||||
= note: required for `&T` to implement `CoerceUnsized<&dyn Bar>`
|
||||
= note: required by cast to type `&dyn Bar`
|
||||
= note: required for the cast from `&T` to `&dyn Bar`
|
||||
|
||||
error[E0038]: the trait `Baz` cannot be made into an object
|
||||
--> $DIR/object-safety-mentions-Self.rs:30:5
|
||||
@ -29,8 +28,7 @@ LL | trait Baz {
|
||||
LL | fn baz(&self) -> Self;
|
||||
| ^^^^ ...because method `baz` references the `Self` type in its return type
|
||||
= help: consider moving `baz` to another trait
|
||||
= note: required for `&T` to implement `CoerceUnsized<&dyn Baz>`
|
||||
= note: required by cast to type `&dyn Baz`
|
||||
= note: required for the cast from `&T` to `&dyn Baz`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
@ -11,8 +11,7 @@ LL | trait Foo {
|
||||
| --- this trait cannot be made into an object...
|
||||
LL | fn foo() {}
|
||||
| ^^^ ...because associated function `foo` has no `self` parameter
|
||||
= note: required for `Box<Bar>` to implement `CoerceUnsized<Box<dyn Foo>>`
|
||||
= note: required by cast to type `Box<dyn Foo>`
|
||||
= note: required for the cast from `Box<Bar>` to `Box<dyn Foo>`
|
||||
help: consider turning `foo` into a method by giving it a `&self` argument
|
||||
|
|
||||
LL | fn foo(&self) {}
|
||||
|
@ -11,8 +11,7 @@ LL | trait Bar
|
||||
| --- this trait cannot be made into an object...
|
||||
LL | where Self : Sized
|
||||
| ^^^^^ ...because it requires `Self: Sized`
|
||||
= note: required for `&T` to implement `CoerceUnsized<&dyn Bar>`
|
||||
= note: required by cast to type `&dyn Bar`
|
||||
= note: required for the cast from `&T` to `&dyn Bar`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -11,8 +11,7 @@ LL | trait Bar : Sized {
|
||||
| --- ^^^^^ ...because it requires `Self: Sized`
|
||||
| |
|
||||
| this trait cannot be made into an object...
|
||||
= note: required for `&T` to implement `CoerceUnsized<&dyn Bar>`
|
||||
= note: required by cast to type `&dyn Bar`
|
||||
= note: required for the cast from `&T` to `&dyn Bar`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -31,8 +31,7 @@ LL | trait Foo {
|
||||
| --- this trait cannot be made into an object...
|
||||
LL | fn foo(self: &Rc<Self>) -> usize;
|
||||
| ^^^^^^^^^ ...because method `foo`'s `self` parameter cannot be dispatched on
|
||||
= note: required for `Rc<usize>` to implement `CoerceUnsized<Rc<dyn Foo>>`
|
||||
= note: required by cast to type `Rc<dyn Foo>`
|
||||
= note: required for the cast from `Rc<usize>` to `Rc<dyn Foo>`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
@ -14,8 +14,7 @@ LL | trait Foo {
|
||||
| --- this trait cannot be made into an object...
|
||||
LL | fn foo(self: &Rc<Self>) -> usize;
|
||||
| ^^^^^^^^^ ...because method `foo`'s `self` parameter cannot be dispatched on
|
||||
= note: required for `Rc<usize>` to implement `CoerceUnsized<Rc<dyn Foo>>`
|
||||
= note: required by cast to type `Rc<dyn Foo>`
|
||||
= note: required for the cast from `Rc<usize>` to `Rc<dyn Foo>`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -36,7 +36,7 @@ LL | impl<T: Debug + Trait> Debug for Inner<T> {
|
||||
| unsatisfied trait bound introduced here
|
||||
= note: 1 redundant requirement hidden
|
||||
= note: required for `&c::Inner<T>` to implement `Debug`
|
||||
= note: required for the cast from `&c::Inner<T>` to the object type `dyn Debug`
|
||||
= note: required for the cast from `&&c::Inner<T>` to `&dyn Debug`
|
||||
= note: this error originates in the derive macro `Debug` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
help: consider restricting type parameter `T`
|
||||
|
|
||||
@ -58,7 +58,7 @@ LL | impl<T> Debug for Inner<T> where T: Debug, T: Trait {
|
||||
| ^^^^^ ^^^^^^^^ ----- unsatisfied trait bound introduced here
|
||||
= note: 1 redundant requirement hidden
|
||||
= note: required for `&d::Inner<T>` to implement `Debug`
|
||||
= note: required for the cast from `&d::Inner<T>` to the object type `dyn Debug`
|
||||
= note: required for the cast from `&&d::Inner<T>` to `&dyn Debug`
|
||||
= note: this error originates in the derive macro `Debug` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
help: consider restricting type parameter `T`
|
||||
|
|
||||
@ -80,7 +80,7 @@ LL | impl<T> Debug for Inner<T> where T: Debug + Trait {
|
||||
| ^^^^^ ^^^^^^^^ ----- unsatisfied trait bound introduced here
|
||||
= note: 1 redundant requirement hidden
|
||||
= note: required for `&e::Inner<T>` to implement `Debug`
|
||||
= note: required for the cast from `&e::Inner<T>` to the object type `dyn Debug`
|
||||
= note: required for the cast from `&&e::Inner<T>` to `&dyn Debug`
|
||||
= note: this error originates in the derive macro `Debug` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
help: consider restricting type parameter `T`
|
||||
|
|
||||
@ -102,7 +102,7 @@ LL | impl<T: Debug> Debug for Inner<T> where T: Trait {
|
||||
| ^^^^^ ^^^^^^^^ ----- unsatisfied trait bound introduced here
|
||||
= note: 1 redundant requirement hidden
|
||||
= note: required for `&f::Inner<T>` to implement `Debug`
|
||||
= note: required for the cast from `&f::Inner<T>` to the object type `dyn Debug`
|
||||
= note: required for the cast from `&&f::Inner<T>` to `&dyn Debug`
|
||||
= note: this error originates in the derive macro `Debug` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
help: consider restricting type parameter `T`
|
||||
|
|
||||
|
@ -1,16 +0,0 @@
|
||||
use std::ffi::{OsStr, OsString};
|
||||
use std::path::Path;
|
||||
|
||||
fn check(p: &dyn AsRef<Path>) {
|
||||
let m = std::fs::metadata(&p);
|
||||
println!("{:?}", &m);
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let s: OsString = ".".into();
|
||||
let s: &OsStr = &s;
|
||||
check(s);
|
||||
//~^ ERROR the size for values of type `[u8]` cannot be known at compilation time
|
||||
//~| HELP within `OsStr`, the trait `Sized` is not implemented for `[u8]`
|
||||
//~| HELP consider borrowing the value, since `&OsStr` can be coerced into `dyn AsRef<Path>`
|
||||
}
|
@ -1,18 +0,0 @@
|
||||
error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
|
||||
--> $DIR/suggest-borrow-to-dyn-object.rs:12:11
|
||||
|
|
||||
LL | check(s);
|
||||
| ^ doesn't have a size known at compile-time
|
||||
|
|
||||
= help: within `OsStr`, the trait `Sized` is not implemented for `[u8]`
|
||||
note: required because it appears within the type `OsStr`
|
||||
--> $SRC_DIR/std/src/ffi/os_str.rs:LL:COL
|
||||
= note: required for the cast from `OsStr` to the object type `dyn AsRef<Path>`
|
||||
help: consider borrowing the value, since `&OsStr` can be coerced into `dyn AsRef<Path>`
|
||||
|
|
||||
LL | check(&s);
|
||||
| +
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0277`.
|
@ -5,7 +5,7 @@ LL | let s: Box<dyn Trait<isize>> = Box::new(Struct { person: "Fred" });
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Trait<isize>` is not implemented for `Struct`
|
||||
|
|
||||
= help: the trait `Trait<&'static str>` is implemented for `Struct`
|
||||
= note: required for the cast from `Struct` to the object type `dyn Trait<isize>`
|
||||
= note: required for the cast from `Box<Struct>` to `Box<dyn Trait<isize>>`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -27,8 +27,7 @@ LL | trait Array: Sized + Copy {}
|
||||
| | |
|
||||
| | ...because it requires `Self: Sized`
|
||||
| this trait cannot be made into an object...
|
||||
= note: required for `&T` to implement `CoerceUnsized<&dyn Array>`
|
||||
= note: required by cast to type `&dyn Array`
|
||||
= note: required for the cast from `&T` to `&dyn Array`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
@ -25,8 +25,7 @@ LL | trait Foo where u32: Q<Self> {
|
||||
| --- ^^^^^^^ ...because it uses `Self` as a type parameter
|
||||
| |
|
||||
| this trait cannot be made into an object...
|
||||
= note: required for `Box<()>` to implement `CoerceUnsized<Box<dyn Foo>>`
|
||||
= note: required by cast to type `Box<dyn Foo>`
|
||||
= note: required for the cast from `Box<()>` to `Box<dyn Foo>`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
@ -12,7 +12,7 @@ note: required because it appears within the type `B`
|
||||
|
|
||||
LL | struct B {
|
||||
| ^
|
||||
= note: required for the cast from `B` to the object type `dyn Foo + Send`
|
||||
= note: required for the cast from `Box<B>` to `Box<dyn Foo + Send>`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user