mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 06:44:35 +00:00
Auto merge of #117135 - matthiaskrgr:rollup-zdh18i6, r=matthiaskrgr
Rollup of 8 pull requests Successful merges: - #116094 (Introduce `-C instrument-coverage=branch` to gate branch coverage) - #116396 (Migrate diagnostics in `rustc_hir_analysis/src/coherence/orphan.rs`) - #116714 (Derive `Ord`, `PartialOrd` and `Hash` for `SocketAddr*`) - #116792 (Avoid unnecessary renumbering during borrowck) - #116841 (Suggest unwrap/expect for let binding type mismatch) - #116943 (Add target features for LoongArch) - #117010 (Add method to convert internal to stable constructs) - #117127 (Remove `#[allow(incomplete_features)]` from RPITIT/AFIT tests) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
151256bd4b
@ -4525,6 +4525,7 @@ dependencies = [
|
||||
"rustc_middle",
|
||||
"rustc_span",
|
||||
"rustc_target",
|
||||
"scoped-tls",
|
||||
"stable_mir",
|
||||
"tracing",
|
||||
]
|
||||
|
@ -81,6 +81,10 @@ impl<'a, 'tcx> MutVisitor<'tcx> for RegionRenumberer<'a, 'tcx> {
|
||||
|
||||
#[instrument(skip(self), level = "debug")]
|
||||
fn visit_ty(&mut self, ty: &mut Ty<'tcx>, ty_context: TyContext) {
|
||||
if matches!(ty_context, TyContext::ReturnTy(_)) {
|
||||
// We will renumber the return ty when called again with `TyContext::LocalDecl`
|
||||
return;
|
||||
}
|
||||
*ty = self.renumber_regions(*ty, || RegionCtxt::TyContext(ty_context));
|
||||
|
||||
debug!(?ty);
|
||||
|
@ -342,6 +342,19 @@ const CSKY_ALLOWED_FEATURES: &[(&str, Option<Symbol>)] = &[
|
||||
("hard-float-abi", Some(sym::csky_target_feature)),
|
||||
// tidy-alphabetical-end
|
||||
];
|
||||
|
||||
const LOONGARCH_ALLOWED_FEATURES: &[(&str, Option<Symbol>)] = &[
|
||||
// tidy-alphabetical-start
|
||||
("d", Some(sym::loongarch_target_feature)),
|
||||
("f", Some(sym::loongarch_target_feature)),
|
||||
("lasx", Some(sym::loongarch_target_feature)),
|
||||
("lbt", Some(sym::loongarch_target_feature)),
|
||||
("lsx", Some(sym::loongarch_target_feature)),
|
||||
("lvz", Some(sym::loongarch_target_feature)),
|
||||
("ual", Some(sym::loongarch_target_feature)),
|
||||
// tidy-alphabetical-end
|
||||
];
|
||||
|
||||
/// When rustdoc is running, provide a list of all known features so that all their respective
|
||||
/// primitives may be documented.
|
||||
///
|
||||
@ -358,6 +371,7 @@ pub fn all_known_features() -> impl Iterator<Item = (&'static str, Option<Symbol
|
||||
.chain(WASM_ALLOWED_FEATURES.iter())
|
||||
.chain(BPF_ALLOWED_FEATURES.iter())
|
||||
.chain(CSKY_ALLOWED_FEATURES)
|
||||
.chain(LOONGARCH_ALLOWED_FEATURES)
|
||||
.cloned()
|
||||
}
|
||||
|
||||
@ -373,6 +387,7 @@ pub fn supported_target_features(sess: &Session) -> &'static [(&'static str, Opt
|
||||
"wasm32" | "wasm64" => WASM_ALLOWED_FEATURES,
|
||||
"bpf" => BPF_ALLOWED_FEATURES,
|
||||
"csky" => CSKY_ALLOWED_FEATURES,
|
||||
"loongarch64" => LOONGARCH_ALLOWED_FEATURES,
|
||||
_ => &[],
|
||||
}
|
||||
}
|
||||
@ -445,6 +460,7 @@ pub fn from_target_feature(
|
||||
Some(sym::bpf_target_feature) => rust_features.bpf_target_feature,
|
||||
Some(sym::aarch64_ver_target_feature) => rust_features.aarch64_ver_target_feature,
|
||||
Some(sym::csky_target_feature) => rust_features.csky_target_feature,
|
||||
Some(sym::loongarch_target_feature) => rust_features.loongarch_target_feature,
|
||||
Some(name) => bug!("unknown target feature gate {}", name),
|
||||
None => true,
|
||||
};
|
||||
|
@ -288,6 +288,7 @@ declare_features! (
|
||||
(unstable, csky_target_feature, "1.73.0", Some(44839), None),
|
||||
(unstable, ermsb_target_feature, "1.49.0", Some(44839), None),
|
||||
(unstable, hexagon_target_feature, "1.27.0", Some(44839), None),
|
||||
(unstable, loongarch_target_feature, "1.73.0", Some(44839), None),
|
||||
(unstable, mips_target_feature, "1.27.0", Some(44839), None),
|
||||
(unstable, powerpc_target_feature, "1.27.0", Some(44839), None),
|
||||
(unstable, riscv_target_feature, "1.45.0", Some(44839), None),
|
||||
|
@ -72,6 +72,12 @@ hir_analysis_copy_impl_on_type_with_dtor =
|
||||
the trait `Copy` cannot be implemented for this type; the type has a destructor
|
||||
.label = `Copy` not allowed on types with destructors
|
||||
|
||||
hir_analysis_cross_crate_traits = cross-crate traits with a default impl, like `{$traits}`, can only be implemented for a struct/enum type, not `{$self_ty}`
|
||||
.label = can't implement cross-crate trait with a default impl for non-struct/enum type
|
||||
|
||||
hir_analysis_cross_crate_traits_defined = cross-crate traits with a default impl, like `{$traits}`, can only be implemented for a struct/enum type defined in the current crate
|
||||
.label = can't implement cross-crate trait for type in another crate
|
||||
|
||||
hir_analysis_dispatch_from_dyn_multi = implementing the `DispatchFromDyn` trait requires multiple coercions
|
||||
.note = the trait `DispatchFromDyn` may only be implemented for a coercion between structures with a single field being coerced
|
||||
.coercions_note = currently, {$number} fields need coercions: {$coercions}
|
||||
@ -237,6 +243,28 @@ hir_analysis_must_implement_not_function_span_note = required by this annotation
|
||||
|
||||
hir_analysis_must_implement_one_of_attribute = the `#[rustc_must_implement_one_of]` attribute must be used with at least 2 args
|
||||
|
||||
hir_analysis_only_current_traits_arbitrary = only traits defined in the current crate can be implemented for arbitrary types
|
||||
|
||||
hir_analysis_only_current_traits_foreign = this is not defined in the current crate because this is a foreign trait
|
||||
|
||||
hir_analysis_only_current_traits_label = impl doesn't use only types from inside the current crate
|
||||
|
||||
hir_analysis_only_current_traits_name = this is not defined in the current crate because {$name} are always foreign
|
||||
|
||||
hir_analysis_only_current_traits_note = define and implement a trait or new type instead
|
||||
|
||||
hir_analysis_only_current_traits_opaque = type alias impl trait is treated as if it were foreign, because its hidden type could be from a foreign crate
|
||||
|
||||
hir_analysis_only_current_traits_outside = only traits defined in the current crate can be implemented for types defined outside of the crate
|
||||
|
||||
hir_analysis_only_current_traits_pointer = `{$pointer}` is not defined in the current crate because raw pointers are always foreign
|
||||
|
||||
hir_analysis_only_current_traits_pointer_sugg = consider introducing a new wrapper type
|
||||
|
||||
hir_analysis_only_current_traits_primitive = only traits defined in the current crate can be implemented for primitive types
|
||||
|
||||
hir_analysis_only_current_traits_ty = `{$ty}` is not defined in the current crate
|
||||
|
||||
hir_analysis_paren_sugar_attribute = the `#[rustc_paren_sugar]` attribute is a temporary means of controlling which traits can use parenthetical notation
|
||||
.help = add `#![feature(unboxed_closures)]` to the crate attributes to use it
|
||||
|
||||
@ -326,6 +354,9 @@ hir_analysis_trait_object_declared_with_no_traits =
|
||||
at least one trait is required for an object type
|
||||
.alias_span = this alias does not contain a trait
|
||||
|
||||
hir_analysis_traits_with_defualt_impl = traits with a default impl, like `{$traits}`, cannot be implemented for {$problematic_kind} `{$self_ty}`
|
||||
.note = a trait object implements `{$traits}` if and only if `{$traits}` is one of the trait object's trait bounds
|
||||
|
||||
hir_analysis_transparent_enum_variant = transparent enum needs exactly one variant, but has {$number}
|
||||
.label = needs exactly one variant, but has {$number}
|
||||
.many_label = too many variants in `{$path}`
|
||||
@ -339,6 +370,16 @@ hir_analysis_transparent_non_zero_sized_enum = the variant of a transparent {$de
|
||||
.label = needs at most one field with non-trivial size or alignment, but has {$field_count}
|
||||
.labels = this field has non-zero size or requires alignment
|
||||
|
||||
hir_analysis_ty_param_first_local = type parameter `{$param_ty}` must be covered by another type when it appears before the first local type (`{$local_type}`)
|
||||
.label = type parameter `{$param_ty}` must be covered by another type when it appears before the first local type (`{$local_type}`)
|
||||
.note = implementing a foreign trait is only possible if at least one of the types for which it is implemented is local, and no uncovered type parameters appear before that first local type
|
||||
.case_note = in this case, 'before' refers to the following order: `impl<..> ForeignTrait<T1, ..., Tn> for T0`, where `T0` is the first and `Tn` is the last
|
||||
|
||||
hir_analysis_ty_param_some = type parameter `{$param_ty}` must be used as the type parameter for some local type (e.g., `MyStruct<{$param_ty}>`)
|
||||
.label = type parameter `{$param_ty}` must be used as the type parameter for some local type
|
||||
.note = implementing a foreign trait is only possible if at least one of the types for which it is implemented is local
|
||||
.only_note = only traits defined in the current crate can be implemented for a type parameter
|
||||
|
||||
hir_analysis_type_of = {$type_of}
|
||||
|
||||
hir_analysis_typeof_reserved_keyword_used =
|
||||
|
@ -2,8 +2,7 @@
|
||||
//! crate or pertains to a type defined in this crate.
|
||||
|
||||
use rustc_data_structures::fx::FxHashSet;
|
||||
use rustc_errors::{struct_span_err, DelayDm};
|
||||
use rustc_errors::{Diagnostic, ErrorGuaranteed};
|
||||
use rustc_errors::{DelayDm, ErrorGuaranteed};
|
||||
use rustc_hir as hir;
|
||||
use rustc_middle::ty::util::CheckRegions;
|
||||
use rustc_middle::ty::GenericArgs;
|
||||
@ -17,6 +16,8 @@ use rustc_span::Span;
|
||||
use rustc_trait_selection::traits;
|
||||
use std::ops::ControlFlow;
|
||||
|
||||
use crate::errors;
|
||||
|
||||
#[instrument(skip(tcx), level = "debug")]
|
||||
pub(crate) fn orphan_check_impl(
|
||||
tcx: TyCtxt<'_>,
|
||||
@ -259,49 +260,30 @@ fn do_orphan_check_impl<'tcx>(
|
||||
match local_impl {
|
||||
LocalImpl::Allow => {}
|
||||
LocalImpl::Disallow { problematic_kind } => {
|
||||
let msg = format!(
|
||||
"traits with a default impl, like `{trait}`, \
|
||||
cannot be implemented for {problematic_kind} `{self_ty}`",
|
||||
trait = tcx.def_path_str(trait_def_id),
|
||||
);
|
||||
let label = format!(
|
||||
"a trait object implements `{trait}` if and only if `{trait}` \
|
||||
is one of the trait object's trait bounds",
|
||||
trait = tcx.def_path_str(trait_def_id),
|
||||
);
|
||||
let sp = tcx.def_span(def_id);
|
||||
let reported =
|
||||
struct_span_err!(tcx.sess, sp, E0321, "{}", msg).note(label).emit();
|
||||
return Err(reported);
|
||||
return Err(tcx.sess.emit_err(errors::TraitsWithDefaultImpl {
|
||||
span: tcx.def_span(def_id),
|
||||
traits: tcx.def_path_str(trait_def_id),
|
||||
problematic_kind,
|
||||
self_ty,
|
||||
}));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if let Some((msg, label)) = match nonlocal_impl {
|
||||
NonlocalImpl::Allow => None,
|
||||
NonlocalImpl::DisallowBecauseNonlocal => Some((
|
||||
format!(
|
||||
"cross-crate traits with a default impl, like `{}`, \
|
||||
can only be implemented for a struct/enum type \
|
||||
defined in the current crate",
|
||||
tcx.def_path_str(trait_def_id)
|
||||
),
|
||||
"can't implement cross-crate trait for type in another crate",
|
||||
)),
|
||||
NonlocalImpl::DisallowOther => Some((
|
||||
format!(
|
||||
"cross-crate traits with a default impl, like `{}`, can \
|
||||
only be implemented for a struct/enum type, not `{}`",
|
||||
tcx.def_path_str(trait_def_id),
|
||||
self_ty
|
||||
),
|
||||
"can't implement cross-crate trait with a default impl for \
|
||||
non-struct/enum type",
|
||||
)),
|
||||
} {
|
||||
let sp = tcx.def_span(def_id);
|
||||
let reported =
|
||||
struct_span_err!(tcx.sess, sp, E0321, "{}", msg).span_label(sp, label).emit();
|
||||
return Err(reported);
|
||||
match nonlocal_impl {
|
||||
NonlocalImpl::Allow => {}
|
||||
NonlocalImpl::DisallowBecauseNonlocal => {
|
||||
return Err(tcx.sess.emit_err(errors::CrossCrateTraitsDefined {
|
||||
span: tcx.def_span(def_id),
|
||||
traits: tcx.def_path_str(trait_def_id),
|
||||
}));
|
||||
}
|
||||
NonlocalImpl::DisallowOther => {
|
||||
return Err(tcx.sess.emit_err(errors::CrossCrateTraits {
|
||||
span: tcx.def_span(def_id),
|
||||
traits: tcx.def_path_str(trait_def_id),
|
||||
self_ty,
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -322,19 +304,18 @@ fn emit_orphan_check_error<'tcx>(
|
||||
let self_ty = trait_ref.self_ty();
|
||||
Err(match err {
|
||||
traits::OrphanCheckErr::NonLocalInputType(tys) => {
|
||||
let msg = match self_ty.kind() {
|
||||
ty::Adt(..) => "can be implemented for types defined outside of the crate",
|
||||
_ if self_ty.is_primitive() => "can be implemented for primitive types",
|
||||
_ => "can be implemented for arbitrary types",
|
||||
};
|
||||
let mut err = struct_span_err!(
|
||||
tcx.sess,
|
||||
sp,
|
||||
E0117,
|
||||
"only traits defined in the current crate {msg}"
|
||||
);
|
||||
err.span_label(sp, "impl doesn't use only types from inside the current crate");
|
||||
let (mut opaque, mut foreign, mut name, mut pointer, mut ty_diag) =
|
||||
(Vec::new(), Vec::new(), Vec::new(), Vec::new(), Vec::new());
|
||||
let mut sugg = None;
|
||||
for &(mut ty, is_target_ty) in &tys {
|
||||
let span = if is_target_ty {
|
||||
// Point at `D<A>` in `impl<A, B> for C<B> in D<A>`
|
||||
self_ty_span
|
||||
} else {
|
||||
// Point at `C<B>` in `impl<A, B> for C<B> in D<A>`
|
||||
trait_span
|
||||
};
|
||||
|
||||
ty = tcx.erase_regions(ty);
|
||||
ty = match ty.kind() {
|
||||
// Remove the type arguments from the output, as they are not relevant.
|
||||
@ -345,50 +326,103 @@ fn emit_orphan_check_error<'tcx>(
|
||||
ty::Adt(def, _) => Ty::new_adt(tcx, *def, ty::List::empty()),
|
||||
_ => ty,
|
||||
};
|
||||
let msg = |ty: &str, postfix: &str| {
|
||||
format!("{ty} is not defined in the current crate{postfix}")
|
||||
};
|
||||
|
||||
let this = |name: &str| {
|
||||
if !trait_ref.def_id.is_local() && !is_target_ty {
|
||||
msg("this", " because this is a foreign trait")
|
||||
fn push_to_foreign_or_name<'tcx>(
|
||||
is_foreign: bool,
|
||||
foreign: &mut Vec<errors::OnlyCurrentTraitsForeign>,
|
||||
name: &mut Vec<errors::OnlyCurrentTraitsName<'tcx>>,
|
||||
span: Span,
|
||||
sname: &'tcx str,
|
||||
) {
|
||||
if is_foreign {
|
||||
foreign.push(errors::OnlyCurrentTraitsForeign { span })
|
||||
} else {
|
||||
msg("this", &format!(" because {name} are always foreign"))
|
||||
name.push(errors::OnlyCurrentTraitsName { span, name: sname });
|
||||
}
|
||||
}
|
||||
|
||||
let is_foreign = !trait_ref.def_id.is_local() && !is_target_ty;
|
||||
|
||||
match &ty.kind() {
|
||||
ty::Slice(_) => {
|
||||
push_to_foreign_or_name(
|
||||
is_foreign,
|
||||
&mut foreign,
|
||||
&mut name,
|
||||
span,
|
||||
"slices",
|
||||
);
|
||||
}
|
||||
ty::Array(..) => {
|
||||
push_to_foreign_or_name(
|
||||
is_foreign,
|
||||
&mut foreign,
|
||||
&mut name,
|
||||
span,
|
||||
"arrays",
|
||||
);
|
||||
}
|
||||
ty::Tuple(..) => {
|
||||
push_to_foreign_or_name(
|
||||
is_foreign,
|
||||
&mut foreign,
|
||||
&mut name,
|
||||
span,
|
||||
"tuples",
|
||||
);
|
||||
}
|
||||
};
|
||||
let msg = match &ty.kind() {
|
||||
ty::Slice(_) => this("slices"),
|
||||
ty::Array(..) => this("arrays"),
|
||||
ty::Tuple(..) => this("tuples"),
|
||||
ty::Alias(ty::Opaque, ..) => {
|
||||
"type alias impl trait is treated as if it were foreign, \
|
||||
because its hidden type could be from a foreign crate"
|
||||
.to_string()
|
||||
opaque.push(errors::OnlyCurrentTraitsOpaque { span })
|
||||
}
|
||||
ty::RawPtr(ptr_ty) => {
|
||||
emit_newtype_suggestion_for_raw_ptr(
|
||||
full_impl_span,
|
||||
self_ty,
|
||||
self_ty_span,
|
||||
ptr_ty,
|
||||
&mut err,
|
||||
);
|
||||
|
||||
msg(&format!("`{ty}`"), " because raw pointers are always foreign")
|
||||
if !self_ty.has_param() {
|
||||
let mut_key = ptr_ty.mutbl.prefix_str();
|
||||
sugg = Some(errors::OnlyCurrentTraitsPointerSugg {
|
||||
wrapper_span: self_ty_span,
|
||||
struct_span: full_impl_span.shrink_to_lo(),
|
||||
mut_key,
|
||||
ptr_ty: ptr_ty.ty,
|
||||
});
|
||||
}
|
||||
pointer.push(errors::OnlyCurrentTraitsPointer { span, pointer: ty });
|
||||
}
|
||||
_ => msg(&format!("`{ty}`"), ""),
|
||||
};
|
||||
|
||||
if is_target_ty {
|
||||
// Point at `D<A>` in `impl<A, B> for C<B> in D<A>`
|
||||
err.span_label(self_ty_span, msg);
|
||||
} else {
|
||||
// Point at `C<B>` in `impl<A, B> for C<B> in D<A>`
|
||||
err.span_label(trait_span, msg);
|
||||
_ => ty_diag.push(errors::OnlyCurrentTraitsTy { span, ty }),
|
||||
}
|
||||
}
|
||||
err.note("define and implement a trait or new type instead");
|
||||
err.emit()
|
||||
|
||||
let err_struct = match self_ty.kind() {
|
||||
ty::Adt(..) => errors::OnlyCurrentTraits::Outside {
|
||||
span: sp,
|
||||
note: (),
|
||||
opaque,
|
||||
foreign,
|
||||
name,
|
||||
pointer,
|
||||
ty: ty_diag,
|
||||
sugg,
|
||||
},
|
||||
_ if self_ty.is_primitive() => errors::OnlyCurrentTraits::Primitive {
|
||||
span: sp,
|
||||
note: (),
|
||||
opaque,
|
||||
foreign,
|
||||
name,
|
||||
pointer,
|
||||
ty: ty_diag,
|
||||
sugg,
|
||||
},
|
||||
_ => errors::OnlyCurrentTraits::Arbitrary {
|
||||
span: sp,
|
||||
note: (),
|
||||
opaque,
|
||||
foreign,
|
||||
name,
|
||||
pointer,
|
||||
ty: ty_diag,
|
||||
sugg,
|
||||
},
|
||||
};
|
||||
tcx.sess.emit_err(err_struct)
|
||||
}
|
||||
traits::OrphanCheckErr::UncoveredTy(param_ty, local_type) => {
|
||||
let mut sp = sp;
|
||||
@ -399,85 +433,18 @@ fn emit_orphan_check_error<'tcx>(
|
||||
}
|
||||
|
||||
match local_type {
|
||||
Some(local_type) => struct_span_err!(
|
||||
tcx.sess,
|
||||
sp,
|
||||
E0210,
|
||||
"type parameter `{}` must be covered by another type \
|
||||
when it appears before the first local type (`{}`)",
|
||||
Some(local_type) => tcx.sess.emit_err(errors::TyParamFirstLocal {
|
||||
span: sp,
|
||||
note: (),
|
||||
param_ty,
|
||||
local_type
|
||||
)
|
||||
.span_label(
|
||||
sp,
|
||||
format!(
|
||||
"type parameter `{param_ty}` must be covered by another type \
|
||||
when it appears before the first local type (`{local_type}`)"
|
||||
),
|
||||
)
|
||||
.note(
|
||||
"implementing a foreign trait is only possible if at \
|
||||
least one of the types for which it is implemented is local, \
|
||||
and no uncovered type parameters appear before that first \
|
||||
local type",
|
||||
)
|
||||
.note(
|
||||
"in this case, 'before' refers to the following order: \
|
||||
`impl<..> ForeignTrait<T1, ..., Tn> for T0`, \
|
||||
where `T0` is the first and `Tn` is the last",
|
||||
)
|
||||
.emit(),
|
||||
None => struct_span_err!(
|
||||
tcx.sess,
|
||||
sp,
|
||||
E0210,
|
||||
"type parameter `{}` must be used as the type parameter for some \
|
||||
local type (e.g., `MyStruct<{}>`)",
|
||||
param_ty,
|
||||
param_ty
|
||||
)
|
||||
.span_label(
|
||||
sp,
|
||||
format!(
|
||||
"type parameter `{param_ty}` must be used as the type parameter for some \
|
||||
local type",
|
||||
),
|
||||
)
|
||||
.note(
|
||||
"implementing a foreign trait is only possible if at \
|
||||
least one of the types for which it is implemented is local",
|
||||
)
|
||||
.note(
|
||||
"only traits defined in the current crate can be \
|
||||
implemented for a type parameter",
|
||||
)
|
||||
.emit(),
|
||||
local_type,
|
||||
}),
|
||||
None => tcx.sess.emit_err(errors::TyParamSome { span: sp, note: (), param_ty }),
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn emit_newtype_suggestion_for_raw_ptr(
|
||||
full_impl_span: Span,
|
||||
self_ty: Ty<'_>,
|
||||
self_ty_span: Span,
|
||||
ptr_ty: &ty::TypeAndMut<'_>,
|
||||
diag: &mut Diagnostic,
|
||||
) {
|
||||
if !self_ty.has_param() {
|
||||
let mut_key = ptr_ty.mutbl.prefix_str();
|
||||
let msg_sugg = "consider introducing a new wrapper type".to_owned();
|
||||
let sugg = vec![
|
||||
(
|
||||
full_impl_span.shrink_to_lo(),
|
||||
format!("struct WrapperType(*{}{});\n\n", mut_key, ptr_ty.ty),
|
||||
),
|
||||
(self_ty_span, "WrapperType".to_owned()),
|
||||
];
|
||||
diag.multipart_suggestion(msg_sugg, sugg, rustc_errors::Applicability::MaybeIncorrect);
|
||||
}
|
||||
}
|
||||
|
||||
/// Lint impls of auto traits if they are likely to have
|
||||
/// unsound or surprising effects on auto impls.
|
||||
fn lint_auto_trait_impl<'tcx>(
|
||||
|
@ -683,7 +683,6 @@ pub(crate) struct SIMDFFIHighlyExperimental {
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
|
||||
pub enum ImplNotMarkedDefault {
|
||||
#[diag(hir_analysis_impl_not_marked_default, code = "E0520")]
|
||||
#[note]
|
||||
@ -1159,3 +1158,174 @@ pub struct ImplForTyRequires {
|
||||
pub trait_name: String,
|
||||
pub ty: String,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(hir_analysis_traits_with_defualt_impl, code = "E0321")]
|
||||
#[note]
|
||||
pub struct TraitsWithDefaultImpl<'a> {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
pub traits: String,
|
||||
pub problematic_kind: &'a str,
|
||||
pub self_ty: Ty<'a>,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(hir_analysis_cross_crate_traits, code = "E0321")]
|
||||
pub struct CrossCrateTraits<'a> {
|
||||
#[primary_span]
|
||||
#[label]
|
||||
pub span: Span,
|
||||
pub traits: String,
|
||||
pub self_ty: Ty<'a>,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(hir_analysis_cross_crate_traits_defined, code = "E0321")]
|
||||
pub struct CrossCrateTraitsDefined {
|
||||
#[primary_span]
|
||||
#[label]
|
||||
pub span: Span,
|
||||
pub traits: String,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(hir_analysis_ty_param_first_local, code = "E0210")]
|
||||
#[note]
|
||||
pub struct TyParamFirstLocal<'a> {
|
||||
#[primary_span]
|
||||
#[label]
|
||||
pub span: Span,
|
||||
#[note(hir_analysis_case_note)]
|
||||
pub note: (),
|
||||
pub param_ty: Ty<'a>,
|
||||
pub local_type: Ty<'a>,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(hir_analysis_ty_param_some, code = "E0210")]
|
||||
#[note]
|
||||
pub struct TyParamSome<'a> {
|
||||
#[primary_span]
|
||||
#[label]
|
||||
pub span: Span,
|
||||
#[note(hir_analysis_only_note)]
|
||||
pub note: (),
|
||||
pub param_ty: Ty<'a>,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
pub enum OnlyCurrentTraits<'a> {
|
||||
#[diag(hir_analysis_only_current_traits_outside, code = "E0117")]
|
||||
Outside {
|
||||
#[primary_span]
|
||||
#[label(hir_analysis_only_current_traits_label)]
|
||||
span: Span,
|
||||
#[note(hir_analysis_only_current_traits_note)]
|
||||
note: (),
|
||||
#[subdiagnostic]
|
||||
opaque: Vec<OnlyCurrentTraitsOpaque>,
|
||||
#[subdiagnostic]
|
||||
foreign: Vec<OnlyCurrentTraitsForeign>,
|
||||
#[subdiagnostic]
|
||||
name: Vec<OnlyCurrentTraitsName<'a>>,
|
||||
#[subdiagnostic]
|
||||
pointer: Vec<OnlyCurrentTraitsPointer<'a>>,
|
||||
#[subdiagnostic]
|
||||
ty: Vec<OnlyCurrentTraitsTy<'a>>,
|
||||
#[subdiagnostic]
|
||||
sugg: Option<OnlyCurrentTraitsPointerSugg<'a>>,
|
||||
},
|
||||
#[diag(hir_analysis_only_current_traits_primitive, code = "E0117")]
|
||||
Primitive {
|
||||
#[primary_span]
|
||||
#[label(hir_analysis_only_current_traits_label)]
|
||||
span: Span,
|
||||
#[note(hir_analysis_only_current_traits_note)]
|
||||
note: (),
|
||||
#[subdiagnostic]
|
||||
opaque: Vec<OnlyCurrentTraitsOpaque>,
|
||||
#[subdiagnostic]
|
||||
foreign: Vec<OnlyCurrentTraitsForeign>,
|
||||
#[subdiagnostic]
|
||||
name: Vec<OnlyCurrentTraitsName<'a>>,
|
||||
#[subdiagnostic]
|
||||
pointer: Vec<OnlyCurrentTraitsPointer<'a>>,
|
||||
#[subdiagnostic]
|
||||
ty: Vec<OnlyCurrentTraitsTy<'a>>,
|
||||
#[subdiagnostic]
|
||||
sugg: Option<OnlyCurrentTraitsPointerSugg<'a>>,
|
||||
},
|
||||
#[diag(hir_analysis_only_current_traits_arbitrary, code = "E0117")]
|
||||
Arbitrary {
|
||||
#[primary_span]
|
||||
#[label(hir_analysis_only_current_traits_label)]
|
||||
span: Span,
|
||||
#[note(hir_analysis_only_current_traits_note)]
|
||||
note: (),
|
||||
#[subdiagnostic]
|
||||
opaque: Vec<OnlyCurrentTraitsOpaque>,
|
||||
#[subdiagnostic]
|
||||
foreign: Vec<OnlyCurrentTraitsForeign>,
|
||||
#[subdiagnostic]
|
||||
name: Vec<OnlyCurrentTraitsName<'a>>,
|
||||
#[subdiagnostic]
|
||||
pointer: Vec<OnlyCurrentTraitsPointer<'a>>,
|
||||
#[subdiagnostic]
|
||||
ty: Vec<OnlyCurrentTraitsTy<'a>>,
|
||||
#[subdiagnostic]
|
||||
sugg: Option<OnlyCurrentTraitsPointerSugg<'a>>,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Subdiagnostic)]
|
||||
#[label(hir_analysis_only_current_traits_opaque)]
|
||||
pub struct OnlyCurrentTraitsOpaque {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(Subdiagnostic)]
|
||||
#[label(hir_analysis_only_current_traits_foreign)]
|
||||
pub struct OnlyCurrentTraitsForeign {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(Subdiagnostic)]
|
||||
#[label(hir_analysis_only_current_traits_name)]
|
||||
pub struct OnlyCurrentTraitsName<'a> {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
pub name: &'a str,
|
||||
}
|
||||
|
||||
#[derive(Subdiagnostic)]
|
||||
#[label(hir_analysis_only_current_traits_pointer)]
|
||||
pub struct OnlyCurrentTraitsPointer<'a> {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
pub pointer: Ty<'a>,
|
||||
}
|
||||
|
||||
#[derive(Subdiagnostic)]
|
||||
#[label(hir_analysis_only_current_traits_ty)]
|
||||
pub struct OnlyCurrentTraitsTy<'a> {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
pub ty: Ty<'a>,
|
||||
}
|
||||
|
||||
#[derive(Subdiagnostic)]
|
||||
#[multipart_suggestion(
|
||||
hir_analysis_only_current_traits_pointer_sugg,
|
||||
applicability = "maybe-incorrect"
|
||||
)]
|
||||
pub struct OnlyCurrentTraitsPointerSugg<'a> {
|
||||
#[suggestion_part(code = "WrapperType")]
|
||||
pub wrapper_span: Span,
|
||||
#[suggestion_part(code = "struct WrapperType(*{mut_key}{ptr_ty});\n\n")]
|
||||
pub struct_span: Span,
|
||||
pub mut_key: &'a str,
|
||||
pub ptr_ty: Ty<'a>,
|
||||
}
|
||||
|
@ -58,7 +58,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
|| self.suggest_into(err, expr, expr_ty, expected)
|
||||
|| self.suggest_floating_point_literal(err, expr, expected)
|
||||
|| self.suggest_null_ptr_for_literal_zero_given_to_ptr_arg(err, expr, expected)
|
||||
|| self.suggest_coercing_result_via_try_operator(err, expr, expected, expr_ty);
|
||||
|| self.suggest_coercing_result_via_try_operator(err, expr, expected, expr_ty)
|
||||
|| self.suggest_missing_unwrap_expect(err, expr, expected, expr_ty);
|
||||
|
||||
if !suggested {
|
||||
self.note_source_of_type_mismatch_constraint(
|
||||
|
@ -6,6 +6,7 @@ use crate::method::probe::{IsSuggestion, Mode, ProbeScope};
|
||||
use rustc_ast::util::parser::{ExprPrecedence, PREC_POSTFIX};
|
||||
use rustc_errors::{Applicability, Diagnostic, MultiSpan};
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def::Res;
|
||||
use rustc_hir::def::{CtorKind, CtorOf, DefKind};
|
||||
use rustc_hir::lang_items::LangItem;
|
||||
use rustc_hir::{
|
||||
@ -1738,4 +1739,83 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
// If the field is hygienic it must come from the same syntax context.
|
||||
&& self.tcx.def_ident_span(field.did).unwrap().normalize_to_macros_2_0().eq_ctxt(span)
|
||||
}
|
||||
|
||||
pub(crate) fn suggest_missing_unwrap_expect(
|
||||
&self,
|
||||
err: &mut Diagnostic,
|
||||
expr: &hir::Expr<'tcx>,
|
||||
expected: Ty<'tcx>,
|
||||
found: Ty<'tcx>,
|
||||
) -> bool {
|
||||
let ty::Adt(adt, args) = found.kind() else { return false };
|
||||
let ret_ty_matches = |diagnostic_item| {
|
||||
if let Some(ret_ty) = self
|
||||
.ret_coercion
|
||||
.as_ref()
|
||||
.map(|c| self.resolve_vars_if_possible(c.borrow().expected_ty()))
|
||||
&& let ty::Adt(kind, _) = ret_ty.kind()
|
||||
&& self.tcx.get_diagnostic_item(diagnostic_item) == Some(kind.did())
|
||||
{
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
};
|
||||
|
||||
// don't suggest anything like `Ok(ok_val).unwrap()` , `Some(some_val).unwrap()`,
|
||||
// `None.unwrap()` etc.
|
||||
let is_ctor = matches!(
|
||||
expr.kind,
|
||||
hir::ExprKind::Call(
|
||||
hir::Expr {
|
||||
kind: hir::ExprKind::Path(hir::QPath::Resolved(
|
||||
None,
|
||||
hir::Path { res: Res::Def(hir::def::DefKind::Ctor(_, _), _), .. },
|
||||
)),
|
||||
..
|
||||
},
|
||||
..,
|
||||
) | hir::ExprKind::Path(hir::QPath::Resolved(
|
||||
None,
|
||||
hir::Path { res: Res::Def(hir::def::DefKind::Ctor(_, _), _), .. },
|
||||
)),
|
||||
);
|
||||
|
||||
let (article, kind, variant, sugg_operator) =
|
||||
if self.tcx.is_diagnostic_item(sym::Result, adt.did()) {
|
||||
("a", "Result", "Err", ret_ty_matches(sym::Result))
|
||||
} else if self.tcx.is_diagnostic_item(sym::Option, adt.did()) {
|
||||
("an", "Option", "None", ret_ty_matches(sym::Option))
|
||||
} else {
|
||||
return false;
|
||||
};
|
||||
if is_ctor || !self.can_coerce(args.type_at(0), expected) {
|
||||
return false;
|
||||
}
|
||||
|
||||
let (msg, sugg) = if sugg_operator {
|
||||
(
|
||||
format!(
|
||||
"use the `?` operator to extract the `{found}` value, propagating \
|
||||
{article} `{kind}::{variant}` value to the caller"
|
||||
),
|
||||
"?",
|
||||
)
|
||||
} else {
|
||||
(
|
||||
format!(
|
||||
"consider using `{kind}::expect` to unwrap the `{found}` value, \
|
||||
panicking if the value is {article} `{kind}::{variant}`"
|
||||
),
|
||||
".expect(\"REASON\")",
|
||||
)
|
||||
};
|
||||
err.span_suggestion_verbose(
|
||||
expr.span.shrink_to_hi(),
|
||||
msg,
|
||||
sugg,
|
||||
Applicability::HasPlaceholders,
|
||||
);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -169,6 +169,9 @@ pub enum MirSpanview {
|
||||
pub enum InstrumentCoverage {
|
||||
/// Default `-C instrument-coverage` or `-C instrument-coverage=statement`
|
||||
All,
|
||||
/// Additionally, instrument branches and output branch coverage.
|
||||
/// `-Zunstable-options -C instrument-coverage=branch`
|
||||
Branch,
|
||||
/// `-Zunstable-options -C instrument-coverage=except-unused-generics`
|
||||
ExceptUnusedGenerics,
|
||||
/// `-Zunstable-options -C instrument-coverage=except-unused-functions`
|
||||
@ -2747,7 +2750,10 @@ pub fn build_session_options(
|
||||
}
|
||||
(Some(InstrumentCoverage::Off | InstrumentCoverage::All), _) => {}
|
||||
(Some(_), _) if !unstable_opts.unstable_options => {
|
||||
handler.early_error("`-C instrument-coverage=except-*` requires `-Z unstable-options`");
|
||||
handler.early_error(
|
||||
"`-C instrument-coverage=branch` and `-C instrument-coverage=except-*` \
|
||||
require `-Z unstable-options`",
|
||||
);
|
||||
}
|
||||
(None, None) => {}
|
||||
(None, ic) => {
|
||||
|
@ -389,7 +389,7 @@ mod desc {
|
||||
pub const parse_mir_spanview: &str = "`statement` (default), `terminator`, or `block`";
|
||||
pub const parse_dump_mono_stats: &str = "`markdown` (default) or `json`";
|
||||
pub const parse_instrument_coverage: &str =
|
||||
"`all` (default), `except-unused-generics`, `except-unused-functions`, or `off`";
|
||||
"`all` (default), `branch`, `except-unused-generics`, `except-unused-functions`, or `off`";
|
||||
pub const parse_instrument_xray: &str = "either a boolean (`yes`, `no`, `on`, `off`, etc), or a comma separated list of settings: `always` or `never` (mutually exclusive), `ignore-loops`, `instruction-threshold=N`, `skip-entry`, `skip-exit`";
|
||||
pub const parse_unpretty: &str = "`string` or `string=string`";
|
||||
pub const parse_treat_err_as_bug: &str = "either no value or a non-negative number";
|
||||
@ -931,6 +931,7 @@ mod parse {
|
||||
|
||||
*slot = Some(match v {
|
||||
"all" => InstrumentCoverage::All,
|
||||
"branch" => InstrumentCoverage::Branch,
|
||||
"except-unused-generics" | "except_unused_generics" => {
|
||||
InstrumentCoverage::ExceptUnusedGenerics
|
||||
}
|
||||
@ -1356,6 +1357,7 @@ options! {
|
||||
reports (note, the compiler build config must include `profiler = true`); \
|
||||
implies `-C symbol-mangling-version=v0`. Optional values are:
|
||||
`=all` (implicit value)
|
||||
`=branch`
|
||||
`=except-unused-generics`
|
||||
`=except-unused-functions`
|
||||
`=off` (default)"),
|
||||
@ -1597,6 +1599,7 @@ options! {
|
||||
reports (note, the compiler build config must include `profiler = true`); \
|
||||
implies `-C symbol-mangling-version=v0`. Optional values are:
|
||||
`=all` (implicit value)
|
||||
`=branch`
|
||||
`=except-unused-generics`
|
||||
`=except-unused-functions`
|
||||
`=off` (default)"),
|
||||
|
@ -702,6 +702,10 @@ impl Session {
|
||||
self.opts.cg.instrument_coverage() != InstrumentCoverage::Off
|
||||
}
|
||||
|
||||
pub fn instrument_coverage_branch(&self) -> bool {
|
||||
self.opts.cg.instrument_coverage() == InstrumentCoverage::Branch
|
||||
}
|
||||
|
||||
pub fn instrument_coverage_except_unused_generics(&self) -> bool {
|
||||
self.opts.cg.instrument_coverage() == InstrumentCoverage::ExceptUnusedGenerics
|
||||
}
|
||||
|
@ -9,6 +9,7 @@ rustc_hir = { path = "../rustc_hir" }
|
||||
rustc_middle = { path = "../rustc_middle" }
|
||||
rustc_span = { path = "../rustc_span" }
|
||||
rustc_target = { path = "../rustc_target" }
|
||||
scoped-tls = "1.0"
|
||||
stable_mir = {path = "../stable_mir" }
|
||||
tracing = "0.1"
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
//! For that, we define APIs that will temporarily be public to 3P that exposes rustc internal APIs
|
||||
//! until stable MIR is complete.
|
||||
|
||||
use crate::rustc_smir::Tables;
|
||||
use crate::rustc_smir::{Stable, Tables, TablesWrapper};
|
||||
use rustc_data_structures::fx;
|
||||
use rustc_data_structures::fx::FxIndexMap;
|
||||
use rustc_middle::mir::interpret::AllocId;
|
||||
@ -11,13 +11,24 @@ use rustc_middle::ty;
|
||||
use rustc_middle::ty::TyCtxt;
|
||||
use rustc_span::def_id::{CrateNum, DefId};
|
||||
use rustc_span::Span;
|
||||
use scoped_tls::scoped_thread_local;
|
||||
use stable_mir::ty::IndexedVal;
|
||||
use std::cell::Cell;
|
||||
use std::cell::RefCell;
|
||||
use std::fmt::Debug;
|
||||
use std::hash::Hash;
|
||||
use std::ops::Index;
|
||||
|
||||
mod internal;
|
||||
|
||||
pub fn stable<'tcx, S: Stable<'tcx>>(item: &S) -> S::T {
|
||||
with_tables(|tables| item.stable(tables))
|
||||
}
|
||||
|
||||
pub fn internal<'tcx, S: RustcInternal<'tcx>>(item: &S) -> S::T {
|
||||
with_tables(|tables| item.internal(tables))
|
||||
}
|
||||
|
||||
impl<'tcx> Index<stable_mir::DefId> for Tables<'tcx> {
|
||||
type Output = DefId;
|
||||
|
||||
@ -125,18 +136,41 @@ pub fn crate_num(item: &stable_mir::Crate) -> CrateNum {
|
||||
item.id.into()
|
||||
}
|
||||
|
||||
// A thread local variable that stores a pointer to the tables mapping between TyCtxt
|
||||
// datastructures and stable MIR datastructures
|
||||
scoped_thread_local! (static TLV: Cell<*const ()>);
|
||||
|
||||
pub(crate) fn init<'tcx>(tables: &TablesWrapper<'tcx>, f: impl FnOnce()) {
|
||||
assert!(!TLV.is_set());
|
||||
let ptr = tables as *const _ as *const ();
|
||||
TLV.set(&Cell::new(ptr), || {
|
||||
f();
|
||||
});
|
||||
}
|
||||
|
||||
/// Loads the current context and calls a function with it.
|
||||
/// Do not nest these, as that will ICE.
|
||||
pub(crate) fn with_tables<'tcx, R>(f: impl FnOnce(&mut Tables<'tcx>) -> R) -> R {
|
||||
assert!(TLV.is_set());
|
||||
TLV.with(|tlv| {
|
||||
let ptr = tlv.get();
|
||||
assert!(!ptr.is_null());
|
||||
let wrapper = ptr as *const TablesWrapper<'tcx>;
|
||||
let mut tables = unsafe { (*wrapper).0.borrow_mut() };
|
||||
f(&mut *tables)
|
||||
})
|
||||
}
|
||||
|
||||
pub fn run(tcx: TyCtxt<'_>, f: impl FnOnce()) {
|
||||
stable_mir::run(
|
||||
Tables {
|
||||
tcx,
|
||||
def_ids: IndexMap::default(),
|
||||
alloc_ids: IndexMap::default(),
|
||||
spans: IndexMap::default(),
|
||||
types: vec![],
|
||||
instances: IndexMap::default(),
|
||||
},
|
||||
f,
|
||||
);
|
||||
let tables = TablesWrapper(RefCell::new(Tables {
|
||||
tcx,
|
||||
def_ids: IndexMap::default(),
|
||||
alloc_ids: IndexMap::default(),
|
||||
spans: IndexMap::default(),
|
||||
types: vec![],
|
||||
instances: IndexMap::default(),
|
||||
}));
|
||||
stable_mir::run(&tables, || init(&tables, f));
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
@ -251,7 +285,7 @@ impl<K: PartialEq + Hash + Eq, V: Copy + Debug + PartialEq + IndexedVal> Index<V
|
||||
/// Trait used to translate a stable construct to its rustc counterpart.
|
||||
///
|
||||
/// This is basically a mirror of [crate::rustc_smir::Stable].
|
||||
pub(crate) trait RustcInternal<'tcx> {
|
||||
pub trait RustcInternal<'tcx> {
|
||||
type T;
|
||||
fn internal(&self, tables: &mut Tables<'tcx>) -> Self::T;
|
||||
}
|
||||
|
@ -23,27 +23,31 @@ use stable_mir::ty::{
|
||||
FloatTy, GenericParamDef, IntTy, LineInfo, Movability, RigidTy, Span, TyKind, UintTy,
|
||||
};
|
||||
use stable_mir::{self, opaque, Context, Filename};
|
||||
use std::cell::RefCell;
|
||||
use tracing::debug;
|
||||
|
||||
mod alloc;
|
||||
mod builder;
|
||||
|
||||
impl<'tcx> Context for Tables<'tcx> {
|
||||
impl<'tcx> Context for TablesWrapper<'tcx> {
|
||||
fn local_crate(&self) -> stable_mir::Crate {
|
||||
smir_crate(self.tcx, LOCAL_CRATE)
|
||||
let tables = self.0.borrow();
|
||||
smir_crate(tables.tcx, LOCAL_CRATE)
|
||||
}
|
||||
|
||||
fn external_crates(&self) -> Vec<stable_mir::Crate> {
|
||||
self.tcx.crates(()).iter().map(|crate_num| smir_crate(self.tcx, *crate_num)).collect()
|
||||
let tables = self.0.borrow();
|
||||
tables.tcx.crates(()).iter().map(|crate_num| smir_crate(tables.tcx, *crate_num)).collect()
|
||||
}
|
||||
|
||||
fn find_crates(&self, name: &str) -> Vec<stable_mir::Crate> {
|
||||
let tables = self.0.borrow();
|
||||
let crates: Vec<stable_mir::Crate> = [LOCAL_CRATE]
|
||||
.iter()
|
||||
.chain(self.tcx.crates(()).iter())
|
||||
.chain(tables.tcx.crates(()).iter())
|
||||
.map(|crate_num| {
|
||||
let crate_name = self.tcx.crate_name(*crate_num).to_string();
|
||||
(name == crate_name).then(|| smir_crate(self.tcx, *crate_num))
|
||||
let crate_name = tables.tcx.crate_name(*crate_num).to_string();
|
||||
(name == crate_name).then(|| smir_crate(tables.tcx, *crate_num))
|
||||
})
|
||||
.into_iter()
|
||||
.filter_map(|c| c)
|
||||
@ -52,163 +56,197 @@ impl<'tcx> Context for Tables<'tcx> {
|
||||
}
|
||||
|
||||
fn name_of_def_id(&self, def_id: stable_mir::DefId) -> String {
|
||||
self.tcx.def_path_str(self[def_id])
|
||||
let tables = self.0.borrow();
|
||||
tables.tcx.def_path_str(tables[def_id])
|
||||
}
|
||||
|
||||
fn span_to_string(&self, span: stable_mir::ty::Span) -> String {
|
||||
self.tcx.sess.source_map().span_to_diagnostic_string(self[span])
|
||||
let tables = self.0.borrow();
|
||||
tables.tcx.sess.source_map().span_to_diagnostic_string(tables[span])
|
||||
}
|
||||
|
||||
fn get_filename(&self, span: &Span) -> Filename {
|
||||
let tables = self.0.borrow();
|
||||
opaque(
|
||||
&self
|
||||
&tables
|
||||
.tcx
|
||||
.sess
|
||||
.source_map()
|
||||
.span_to_filename(self[*span])
|
||||
.span_to_filename(tables[*span])
|
||||
.display(rustc_span::FileNameDisplayPreference::Local)
|
||||
.to_string(),
|
||||
)
|
||||
}
|
||||
|
||||
fn get_lines(&self, span: &Span) -> LineInfo {
|
||||
let lines = &self.tcx.sess.source_map().span_to_location_info(self[*span]);
|
||||
let tables = self.0.borrow();
|
||||
let lines = &tables.tcx.sess.source_map().span_to_location_info(tables[*span]);
|
||||
LineInfo { start_line: lines.1, start_col: lines.2, end_line: lines.3, end_col: lines.4 }
|
||||
}
|
||||
|
||||
fn def_kind(&mut self, def_id: stable_mir::DefId) -> stable_mir::DefKind {
|
||||
self.tcx.def_kind(self[def_id]).stable(self)
|
||||
fn def_kind(&self, def_id: stable_mir::DefId) -> stable_mir::DefKind {
|
||||
let mut tables = self.0.borrow_mut();
|
||||
tables.tcx.def_kind(tables[def_id]).stable(&mut *tables)
|
||||
}
|
||||
|
||||
fn span_of_an_item(&mut self, def_id: stable_mir::DefId) -> Span {
|
||||
self.tcx.def_span(self[def_id]).stable(self)
|
||||
fn span_of_an_item(&self, def_id: stable_mir::DefId) -> Span {
|
||||
let mut tables = self.0.borrow_mut();
|
||||
tables.tcx.def_span(tables[def_id]).stable(&mut *tables)
|
||||
}
|
||||
|
||||
fn all_local_items(&mut self) -> stable_mir::CrateItems {
|
||||
self.tcx.mir_keys(()).iter().map(|item| self.crate_item(item.to_def_id())).collect()
|
||||
fn all_local_items(&self) -> stable_mir::CrateItems {
|
||||
let mut tables = self.0.borrow_mut();
|
||||
tables.tcx.mir_keys(()).iter().map(|item| tables.crate_item(item.to_def_id())).collect()
|
||||
}
|
||||
|
||||
fn entry_fn(&mut self) -> Option<stable_mir::CrateItem> {
|
||||
Some(self.crate_item(self.tcx.entry_fn(())?.0))
|
||||
fn entry_fn(&self) -> Option<stable_mir::CrateItem> {
|
||||
let mut tables = self.0.borrow_mut();
|
||||
let tcx = tables.tcx;
|
||||
Some(tables.crate_item(tcx.entry_fn(())?.0))
|
||||
}
|
||||
|
||||
fn all_trait_decls(&mut self) -> stable_mir::TraitDecls {
|
||||
self.tcx
|
||||
fn all_trait_decls(&self) -> stable_mir::TraitDecls {
|
||||
let mut tables = self.0.borrow_mut();
|
||||
tables
|
||||
.tcx
|
||||
.traits(LOCAL_CRATE)
|
||||
.iter()
|
||||
.map(|trait_def_id| self.trait_def(*trait_def_id))
|
||||
.map(|trait_def_id| tables.trait_def(*trait_def_id))
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn trait_decl(&mut self, trait_def: &stable_mir::ty::TraitDef) -> stable_mir::ty::TraitDecl {
|
||||
let def_id = self[trait_def.0];
|
||||
let trait_def = self.tcx.trait_def(def_id);
|
||||
trait_def.stable(self)
|
||||
fn trait_decl(&self, trait_def: &stable_mir::ty::TraitDef) -> stable_mir::ty::TraitDecl {
|
||||
let mut tables = self.0.borrow_mut();
|
||||
let def_id = tables[trait_def.0];
|
||||
let trait_def = tables.tcx.trait_def(def_id);
|
||||
trait_def.stable(&mut *tables)
|
||||
}
|
||||
|
||||
fn all_trait_impls(&mut self) -> stable_mir::ImplTraitDecls {
|
||||
self.tcx
|
||||
fn all_trait_impls(&self) -> stable_mir::ImplTraitDecls {
|
||||
let mut tables = self.0.borrow_mut();
|
||||
tables
|
||||
.tcx
|
||||
.trait_impls_in_crate(LOCAL_CRATE)
|
||||
.iter()
|
||||
.map(|impl_def_id| self.impl_def(*impl_def_id))
|
||||
.map(|impl_def_id| tables.impl_def(*impl_def_id))
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn trait_impl(&mut self, impl_def: &stable_mir::ty::ImplDef) -> stable_mir::ty::ImplTrait {
|
||||
let def_id = self[impl_def.0];
|
||||
let impl_trait = self.tcx.impl_trait_ref(def_id).unwrap();
|
||||
impl_trait.stable(self)
|
||||
fn trait_impl(&self, impl_def: &stable_mir::ty::ImplDef) -> stable_mir::ty::ImplTrait {
|
||||
let mut tables = self.0.borrow_mut();
|
||||
let def_id = tables[impl_def.0];
|
||||
let impl_trait = tables.tcx.impl_trait_ref(def_id).unwrap();
|
||||
impl_trait.stable(&mut *tables)
|
||||
}
|
||||
|
||||
fn mir_body(&mut self, item: stable_mir::DefId) -> stable_mir::mir::Body {
|
||||
let def_id = self[item];
|
||||
self.tcx.instance_mir(ty::InstanceDef::Item(def_id)).stable(self)
|
||||
fn mir_body(&self, item: stable_mir::DefId) -> stable_mir::mir::Body {
|
||||
let mut tables = self.0.borrow_mut();
|
||||
let def_id = tables[item];
|
||||
tables.tcx.instance_mir(ty::InstanceDef::Item(def_id)).stable(&mut tables)
|
||||
}
|
||||
|
||||
fn ty_kind(&mut self, ty: stable_mir::ty::Ty) -> TyKind {
|
||||
self.types[ty.0].clone().stable(self)
|
||||
fn ty_kind(&self, ty: stable_mir::ty::Ty) -> TyKind {
|
||||
let mut tables = self.0.borrow_mut();
|
||||
tables.types[ty.0].clone().stable(&mut *tables)
|
||||
}
|
||||
|
||||
fn mk_ty(&mut self, kind: TyKind) -> stable_mir::ty::Ty {
|
||||
let n = self.types.len();
|
||||
self.types.push(MaybeStable::Stable(kind));
|
||||
fn mk_ty(&self, kind: TyKind) -> stable_mir::ty::Ty {
|
||||
let mut tables = self.0.borrow_mut();
|
||||
let n = tables.types.len();
|
||||
tables.types.push(MaybeStable::Stable(kind));
|
||||
stable_mir::ty::Ty(n)
|
||||
}
|
||||
|
||||
fn generics_of(&mut self, def_id: stable_mir::DefId) -> stable_mir::ty::Generics {
|
||||
let def_id = self[def_id];
|
||||
let generics = self.tcx.generics_of(def_id);
|
||||
generics.stable(self)
|
||||
fn generics_of(&self, def_id: stable_mir::DefId) -> stable_mir::ty::Generics {
|
||||
let mut tables = self.0.borrow_mut();
|
||||
let def_id = tables[def_id];
|
||||
let generics = tables.tcx.generics_of(def_id);
|
||||
generics.stable(&mut *tables)
|
||||
}
|
||||
|
||||
fn predicates_of(&mut self, def_id: stable_mir::DefId) -> stable_mir::ty::GenericPredicates {
|
||||
let def_id = self[def_id];
|
||||
let ty::GenericPredicates { parent, predicates } = self.tcx.predicates_of(def_id);
|
||||
fn predicates_of(&self, def_id: stable_mir::DefId) -> stable_mir::ty::GenericPredicates {
|
||||
let mut tables = self.0.borrow_mut();
|
||||
let def_id = tables[def_id];
|
||||
let ty::GenericPredicates { parent, predicates } = tables.tcx.predicates_of(def_id);
|
||||
stable_mir::ty::GenericPredicates {
|
||||
parent: parent.map(|did| self.trait_def(did)),
|
||||
parent: parent.map(|did| tables.trait_def(did)),
|
||||
predicates: predicates
|
||||
.iter()
|
||||
.map(|(clause, span)| {
|
||||
(clause.as_predicate().kind().skip_binder().stable(self), span.stable(self))
|
||||
(
|
||||
clause.as_predicate().kind().skip_binder().stable(&mut *tables),
|
||||
span.stable(&mut *tables),
|
||||
)
|
||||
})
|
||||
.collect(),
|
||||
}
|
||||
}
|
||||
|
||||
fn explicit_predicates_of(
|
||||
&mut self,
|
||||
&self,
|
||||
def_id: stable_mir::DefId,
|
||||
) -> stable_mir::ty::GenericPredicates {
|
||||
let def_id = self[def_id];
|
||||
let ty::GenericPredicates { parent, predicates } = self.tcx.explicit_predicates_of(def_id);
|
||||
let mut tables = self.0.borrow_mut();
|
||||
let def_id = tables[def_id];
|
||||
let ty::GenericPredicates { parent, predicates } =
|
||||
tables.tcx.explicit_predicates_of(def_id);
|
||||
stable_mir::ty::GenericPredicates {
|
||||
parent: parent.map(|did| self.trait_def(did)),
|
||||
parent: parent.map(|did| tables.trait_def(did)),
|
||||
predicates: predicates
|
||||
.iter()
|
||||
.map(|(clause, span)| {
|
||||
(clause.as_predicate().kind().skip_binder().stable(self), span.stable(self))
|
||||
(
|
||||
clause.as_predicate().kind().skip_binder().stable(&mut *tables),
|
||||
span.stable(&mut *tables),
|
||||
)
|
||||
})
|
||||
.collect(),
|
||||
}
|
||||
}
|
||||
|
||||
fn instance_body(&mut self, def: InstanceDef) -> Body {
|
||||
let instance = self.instances[def];
|
||||
builder::BodyBuilder::new(self.tcx, instance).build(self)
|
||||
fn instance_body(&self, def: InstanceDef) -> Body {
|
||||
let mut tables = self.0.borrow_mut();
|
||||
let instance = tables.instances[def];
|
||||
builder::BodyBuilder::new(tables.tcx, instance).build(&mut *tables)
|
||||
}
|
||||
|
||||
fn instance_ty(&mut self, def: InstanceDef) -> stable_mir::ty::Ty {
|
||||
let instance = self.instances[def];
|
||||
let ty = instance.ty(self.tcx, ParamEnv::empty());
|
||||
self.intern_ty(ty)
|
||||
fn instance_ty(&self, def: InstanceDef) -> stable_mir::ty::Ty {
|
||||
let mut tables = self.0.borrow_mut();
|
||||
let instance = tables.instances[def];
|
||||
let ty = instance.ty(tables.tcx, ParamEnv::empty());
|
||||
tables.intern_ty(ty)
|
||||
}
|
||||
|
||||
fn instance_def_id(&mut self, def: InstanceDef) -> stable_mir::DefId {
|
||||
let def_id = self.instances[def].def_id();
|
||||
self.create_def_id(def_id)
|
||||
fn instance_def_id(&self, def: InstanceDef) -> stable_mir::DefId {
|
||||
let mut tables = self.0.borrow_mut();
|
||||
let def_id = tables.instances[def].def_id();
|
||||
tables.create_def_id(def_id)
|
||||
}
|
||||
|
||||
fn mono_instance(&mut self, item: stable_mir::CrateItem) -> stable_mir::mir::mono::Instance {
|
||||
let def_id = self[item.0];
|
||||
Instance::mono(self.tcx, def_id).stable(self)
|
||||
fn mono_instance(&self, item: stable_mir::CrateItem) -> stable_mir::mir::mono::Instance {
|
||||
let mut tables = self.0.borrow_mut();
|
||||
let def_id = tables[item.0];
|
||||
Instance::mono(tables.tcx, def_id).stable(&mut *tables)
|
||||
}
|
||||
|
||||
fn requires_monomorphization(&self, def_id: stable_mir::DefId) -> bool {
|
||||
let def_id = self[def_id];
|
||||
let generics = self.tcx.generics_of(def_id);
|
||||
let result = generics.requires_monomorphization(self.tcx);
|
||||
let tables = self.0.borrow();
|
||||
let def_id = tables[def_id];
|
||||
let generics = tables.tcx.generics_of(def_id);
|
||||
let result = generics.requires_monomorphization(tables.tcx);
|
||||
result
|
||||
}
|
||||
|
||||
fn resolve_instance(
|
||||
&mut self,
|
||||
&self,
|
||||
def: stable_mir::ty::FnDef,
|
||||
args: &stable_mir::ty::GenericArgs,
|
||||
) -> Option<stable_mir::mir::mono::Instance> {
|
||||
let def_id = def.0.internal(self);
|
||||
let args_ref = args.internal(self);
|
||||
match Instance::resolve(self.tcx, ParamEnv::reveal_all(), def_id, args_ref) {
|
||||
Ok(Some(instance)) => Some(instance.stable(self)),
|
||||
let mut tables = self.0.borrow_mut();
|
||||
let def_id = def.0.internal(&mut *tables);
|
||||
let args_ref = args.internal(&mut *tables);
|
||||
match Instance::resolve(tables.tcx, ParamEnv::reveal_all(), def_id, args_ref) {
|
||||
Ok(Some(instance)) => Some(instance.stable(&mut *tables)),
|
||||
Ok(None) | Err(_) => None,
|
||||
}
|
||||
}
|
||||
@ -241,13 +279,15 @@ impl<S, R: PartialEq> PartialEq<R> for MaybeStable<S, R> {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) struct TablesWrapper<'tcx>(pub(crate) RefCell<Tables<'tcx>>);
|
||||
|
||||
pub struct Tables<'tcx> {
|
||||
pub tcx: TyCtxt<'tcx>,
|
||||
pub def_ids: IndexMap<DefId, stable_mir::DefId>,
|
||||
pub alloc_ids: IndexMap<AllocId, stable_mir::AllocId>,
|
||||
pub spans: IndexMap<rustc_span::Span, Span>,
|
||||
pub types: Vec<MaybeStable<TyKind, Ty<'tcx>>>,
|
||||
pub instances: IndexMap<ty::Instance<'tcx>, InstanceDef>,
|
||||
pub(crate) tcx: TyCtxt<'tcx>,
|
||||
pub(crate) def_ids: IndexMap<DefId, stable_mir::DefId>,
|
||||
pub(crate) alloc_ids: IndexMap<AllocId, stable_mir::AllocId>,
|
||||
pub(crate) spans: IndexMap<rustc_span::Span, Span>,
|
||||
pub(crate) types: Vec<MaybeStable<TyKind, Ty<'tcx>>>,
|
||||
pub(crate) instances: IndexMap<ty::Instance<'tcx>, InstanceDef>,
|
||||
}
|
||||
|
||||
impl<'tcx> Tables<'tcx> {
|
||||
@ -270,7 +310,7 @@ fn smir_crate(tcx: TyCtxt<'_>, crate_num: CrateNum) -> stable_mir::Crate {
|
||||
}
|
||||
|
||||
/// Trait used to convert between an internal MIR type to a Stable MIR type.
|
||||
pub(crate) trait Stable<'tcx> {
|
||||
pub trait Stable<'tcx> {
|
||||
/// The stable representation of the type implementing Stable.
|
||||
type T;
|
||||
/// Converts an object to the equivalent Stable MIR representation.
|
||||
|
@ -957,6 +957,7 @@ symbols! {
|
||||
log_syntax,
|
||||
logf32,
|
||||
logf64,
|
||||
loongarch_target_feature,
|
||||
loop_break_value,
|
||||
lt,
|
||||
macro_at_most_once_rep,
|
||||
|
@ -175,17 +175,17 @@ pub fn trait_impl(trait_impl: &ImplDef) -> ImplTrait {
|
||||
}
|
||||
|
||||
pub trait Context {
|
||||
fn entry_fn(&mut self) -> Option<CrateItem>;
|
||||
fn entry_fn(&self) -> Option<CrateItem>;
|
||||
/// Retrieve all items of the local crate that have a MIR associated with them.
|
||||
fn all_local_items(&mut self) -> CrateItems;
|
||||
fn mir_body(&mut self, item: DefId) -> mir::Body;
|
||||
fn all_trait_decls(&mut self) -> TraitDecls;
|
||||
fn trait_decl(&mut self, trait_def: &TraitDef) -> TraitDecl;
|
||||
fn all_trait_impls(&mut self) -> ImplTraitDecls;
|
||||
fn trait_impl(&mut self, trait_impl: &ImplDef) -> ImplTrait;
|
||||
fn generics_of(&mut self, def_id: DefId) -> Generics;
|
||||
fn predicates_of(&mut self, def_id: DefId) -> GenericPredicates;
|
||||
fn explicit_predicates_of(&mut self, def_id: DefId) -> GenericPredicates;
|
||||
fn all_local_items(&self) -> CrateItems;
|
||||
fn mir_body(&self, item: DefId) -> mir::Body;
|
||||
fn all_trait_decls(&self) -> TraitDecls;
|
||||
fn trait_decl(&self, trait_def: &TraitDef) -> TraitDecl;
|
||||
fn all_trait_impls(&self) -> ImplTraitDecls;
|
||||
fn trait_impl(&self, trait_impl: &ImplDef) -> ImplTrait;
|
||||
fn generics_of(&self, def_id: DefId) -> Generics;
|
||||
fn predicates_of(&self, def_id: DefId) -> GenericPredicates;
|
||||
fn explicit_predicates_of(&self, def_id: DefId) -> GenericPredicates;
|
||||
/// Get information about the local crate.
|
||||
fn local_crate(&self) -> Crate;
|
||||
/// Retrieve a list of all external crates.
|
||||
@ -207,61 +207,58 @@ pub trait Context {
|
||||
fn get_lines(&self, span: &Span) -> LineInfo;
|
||||
|
||||
/// Returns the `kind` of given `DefId`
|
||||
fn def_kind(&mut self, def_id: DefId) -> DefKind;
|
||||
fn def_kind(&self, def_id: DefId) -> DefKind;
|
||||
|
||||
/// `Span` of an item
|
||||
fn span_of_an_item(&mut self, def_id: DefId) -> Span;
|
||||
fn span_of_an_item(&self, def_id: DefId) -> Span;
|
||||
|
||||
/// Obtain the representation of a type.
|
||||
fn ty_kind(&mut self, ty: Ty) -> TyKind;
|
||||
fn ty_kind(&self, ty: Ty) -> TyKind;
|
||||
|
||||
/// Create a new `Ty` from scratch without information from rustc.
|
||||
fn mk_ty(&mut self, kind: TyKind) -> Ty;
|
||||
fn mk_ty(&self, kind: TyKind) -> Ty;
|
||||
|
||||
/// Get the body of an Instance.
|
||||
/// FIXME: Monomorphize the body.
|
||||
fn instance_body(&mut self, instance: InstanceDef) -> Body;
|
||||
fn instance_body(&self, instance: InstanceDef) -> Body;
|
||||
|
||||
/// Get the instance type with generic substitutions applied and lifetimes erased.
|
||||
fn instance_ty(&mut self, instance: InstanceDef) -> Ty;
|
||||
fn instance_ty(&self, instance: InstanceDef) -> Ty;
|
||||
|
||||
/// Get the instance.
|
||||
fn instance_def_id(&mut self, instance: InstanceDef) -> DefId;
|
||||
fn instance_def_id(&self, instance: InstanceDef) -> DefId;
|
||||
|
||||
/// Convert a non-generic crate item into an instance.
|
||||
/// This function will panic if the item is generic.
|
||||
fn mono_instance(&mut self, item: CrateItem) -> Instance;
|
||||
fn mono_instance(&self, item: CrateItem) -> Instance;
|
||||
|
||||
/// Item requires monomorphization.
|
||||
fn requires_monomorphization(&self, def_id: DefId) -> bool;
|
||||
|
||||
/// Resolve an instance from the given function definition and generic arguments.
|
||||
fn resolve_instance(&mut self, def: FnDef, args: &GenericArgs) -> Option<Instance>;
|
||||
fn resolve_instance(&self, def: FnDef, args: &GenericArgs) -> Option<Instance>;
|
||||
}
|
||||
|
||||
// A thread local variable that stores a pointer to the tables mapping between TyCtxt
|
||||
// datastructures and stable MIR datastructures
|
||||
scoped_thread_local! (static TLV: Cell<*mut ()>);
|
||||
scoped_thread_local! (static TLV: Cell<*const ()>);
|
||||
|
||||
pub fn run(mut context: impl Context, f: impl FnOnce()) {
|
||||
pub fn run(context: &dyn Context, f: impl FnOnce()) {
|
||||
assert!(!TLV.is_set());
|
||||
fn g<'a>(mut context: &mut (dyn Context + 'a), f: impl FnOnce()) {
|
||||
let ptr: *mut () = &mut context as *mut &mut _ as _;
|
||||
TLV.set(&Cell::new(ptr), || {
|
||||
f();
|
||||
});
|
||||
}
|
||||
g(&mut context, f);
|
||||
let ptr: *const () = &context as *const &_ as _;
|
||||
TLV.set(&Cell::new(ptr), || {
|
||||
f();
|
||||
});
|
||||
}
|
||||
|
||||
/// Loads the current context and calls a function with it.
|
||||
/// Do not nest these, as that will ICE.
|
||||
pub fn with<R>(f: impl FnOnce(&mut dyn Context) -> R) -> R {
|
||||
pub fn with<R>(f: impl FnOnce(&dyn Context) -> R) -> R {
|
||||
assert!(TLV.is_set());
|
||||
TLV.with(|tlv| {
|
||||
let ptr = tlv.get();
|
||||
assert!(!ptr.is_null());
|
||||
f(unsafe { *(ptr as *mut &mut dyn Context) })
|
||||
f(unsafe { *(ptr as *const &dyn Context) })
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,4 @@
|
||||
use crate::cmp::Ordering;
|
||||
use crate::fmt::{self, Write};
|
||||
use crate::hash;
|
||||
use crate::net::{IpAddr, Ipv4Addr, Ipv6Addr};
|
||||
|
||||
use super::display_buffer::DisplayBuffer;
|
||||
@ -63,7 +61,7 @@ pub enum SocketAddr {
|
||||
/// assert_eq!(socket.ip(), &Ipv4Addr::new(127, 0, 0, 1));
|
||||
/// assert_eq!(socket.port(), 8080);
|
||||
/// ```
|
||||
#[derive(Copy, Clone, Eq, PartialEq)]
|
||||
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub struct SocketAddrV4 {
|
||||
ip: Ipv4Addr,
|
||||
@ -96,7 +94,7 @@ pub struct SocketAddrV4 {
|
||||
/// assert_eq!(socket.ip(), &Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 1));
|
||||
/// assert_eq!(socket.port(), 8080);
|
||||
/// ```
|
||||
#[derive(Copy, Clone, Eq, PartialEq)]
|
||||
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub struct SocketAddrV6 {
|
||||
ip: Ipv6Addr,
|
||||
@ -644,48 +642,3 @@ impl fmt::Debug for SocketAddrV6 {
|
||||
fmt::Display::fmt(self, fmt)
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "socketaddr_ordering", since = "1.45.0")]
|
||||
impl PartialOrd for SocketAddrV4 {
|
||||
#[inline]
|
||||
fn partial_cmp(&self, other: &SocketAddrV4) -> Option<Ordering> {
|
||||
Some(self.cmp(other))
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "socketaddr_ordering", since = "1.45.0")]
|
||||
impl PartialOrd for SocketAddrV6 {
|
||||
#[inline]
|
||||
fn partial_cmp(&self, other: &SocketAddrV6) -> Option<Ordering> {
|
||||
Some(self.cmp(other))
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "socketaddr_ordering", since = "1.45.0")]
|
||||
impl Ord for SocketAddrV4 {
|
||||
#[inline]
|
||||
fn cmp(&self, other: &SocketAddrV4) -> Ordering {
|
||||
self.ip().cmp(other.ip()).then(self.port().cmp(&other.port()))
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "socketaddr_ordering", since = "1.45.0")]
|
||||
impl Ord for SocketAddrV6 {
|
||||
#[inline]
|
||||
fn cmp(&self, other: &SocketAddrV6) -> Ordering {
|
||||
self.ip().cmp(other.ip()).then(self.port().cmp(&other.port()))
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl hash::Hash for SocketAddrV4 {
|
||||
fn hash<H: hash::Hasher>(&self, s: &mut H) {
|
||||
(self.port, self.ip).hash(s)
|
||||
}
|
||||
}
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl hash::Hash for SocketAddrV6 {
|
||||
fn hash<H: hash::Hasher>(&self, s: &mut H) {
|
||||
(self.port, &self.ip, self.flowinfo, self.scope_id).hash(s)
|
||||
}
|
||||
}
|
||||
|
@ -199,6 +199,9 @@ fn compare() {
|
||||
let v6_1 = "[2001:db8:f00::1002]:23456".parse::<SocketAddrV6>().unwrap();
|
||||
let v6_2 = "[2001:db8:f00::2001]:12345".parse::<SocketAddrV6>().unwrap();
|
||||
let v6_3 = "[2001:db8:f00::2001]:23456".parse::<SocketAddrV6>().unwrap();
|
||||
let v6_4 = "[2001:db8:f00::2001%42]:23456".parse::<SocketAddrV6>().unwrap();
|
||||
let mut v6_5 = "[2001:db8:f00::2001]:23456".parse::<SocketAddrV6>().unwrap();
|
||||
v6_5.set_flowinfo(17);
|
||||
|
||||
// equality
|
||||
assert_eq!(v4_1, v4_1);
|
||||
@ -207,6 +210,8 @@ fn compare() {
|
||||
assert_eq!(SocketAddr::V6(v6_1), SocketAddr::V6(v6_1));
|
||||
assert!(v4_1 != v4_2);
|
||||
assert!(v6_1 != v6_2);
|
||||
assert!(v6_3 != v6_4);
|
||||
assert!(v6_3 != v6_5);
|
||||
|
||||
// compare different addresses
|
||||
assert!(v4_1 < v4_2);
|
||||
@ -226,6 +231,12 @@ fn compare() {
|
||||
assert!(v4_3 > v4_1);
|
||||
assert!(v6_3 > v6_1);
|
||||
|
||||
// compare the same address with different scope_id
|
||||
assert!(v6_3 < v6_4);
|
||||
|
||||
// compare the same address with different flowinfo
|
||||
assert!(v6_3 < v6_5);
|
||||
|
||||
// compare with an inferred right-hand side
|
||||
assert_eq!(v4_1, "224.120.45.1:23456".parse().unwrap());
|
||||
assert_eq!(v6_1, "[2001:db8:f00::1002]:23456".parse().unwrap());
|
||||
|
@ -1,5 +1,5 @@
|
||||
// run-pass
|
||||
// Test that users are able to use stable mir APIs to retrieve monomorphized instances
|
||||
//! Test that users are able to use stable mir APIs to retrieve monomorphized instances
|
||||
|
||||
// ignore-stage1
|
||||
// ignore-cross-compile
|
||||
@ -14,15 +14,15 @@
|
||||
extern crate rustc_middle;
|
||||
#[macro_use]
|
||||
extern crate rustc_smir;
|
||||
extern crate stable_mir;
|
||||
extern crate rustc_driver;
|
||||
extern crate rustc_interface;
|
||||
extern crate stable_mir;
|
||||
|
||||
use rustc_middle::ty::TyCtxt;
|
||||
use mir::{mono::Instance, TerminatorKind::*};
|
||||
use stable_mir::ty::{TyKind, RigidTy};
|
||||
use stable_mir::*;
|
||||
use rustc_middle::ty::TyCtxt;
|
||||
use rustc_smir::rustc_internal;
|
||||
use stable_mir::ty::{RigidTy, TyKind};
|
||||
use stable_mir::*;
|
||||
use std::io::Write;
|
||||
use std::ops::ControlFlow;
|
||||
|
||||
@ -33,16 +33,16 @@ fn test_stable_mir(_tcx: TyCtxt<'_>) -> ControlFlow<()> {
|
||||
let items = stable_mir::all_local_items();
|
||||
|
||||
// Get all items and split generic vs monomorphic items.
|
||||
let (generic, mono) : (Vec<_>, Vec<_>) = items.into_iter().partition(|item| {
|
||||
item.requires_monomorphization()
|
||||
});
|
||||
let (generic, mono): (Vec<_>, Vec<_>) =
|
||||
items.into_iter().partition(|item| item.requires_monomorphization());
|
||||
assert_eq!(mono.len(), 3, "Expected 2 mono functions and one constant");
|
||||
assert_eq!(generic.len(), 2, "Expected 2 generic functions");
|
||||
|
||||
// For all monomorphic items, get the correspondent instances.
|
||||
let instances = mono.iter().filter_map(|item| {
|
||||
mir::mono::Instance::try_from(*item).ok()
|
||||
}).collect::<Vec<mir::mono::Instance>>();
|
||||
let instances = mono
|
||||
.iter()
|
||||
.filter_map(|item| mir::mono::Instance::try_from(*item).ok())
|
||||
.collect::<Vec<mir::mono::Instance>>();
|
||||
assert_eq!(instances.len(), mono.len());
|
||||
|
||||
// For all generic items, try_from should fail.
|
||||
@ -58,19 +58,22 @@ fn test_stable_mir(_tcx: TyCtxt<'_>) -> ControlFlow<()> {
|
||||
fn test_body(body: mir::Body) {
|
||||
for term in body.blocks.iter().map(|bb| &bb.terminator) {
|
||||
match &term.kind {
|
||||
Call{ func, .. } => {
|
||||
Call { func, .. } => {
|
||||
let TyKind::RigidTy(ty) = func.ty(&body.locals).kind() else { unreachable!() };
|
||||
let RigidTy::FnDef(def, args) = ty else { unreachable!() };
|
||||
let result = Instance::resolve(def, &args);
|
||||
assert!(result.is_ok());
|
||||
}
|
||||
Goto {..} | Assert{..} | SwitchInt{..} | Return | Drop {..} => { /* Do nothing */}
|
||||
_ => { unreachable!("Unexpected terminator {term:?}") }
|
||||
Goto { .. } | Assert { .. } | SwitchInt { .. } | Return | Drop { .. } => {
|
||||
/* Do nothing */
|
||||
}
|
||||
_ => {
|
||||
unreachable!("Unexpected terminator {term:?}")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// This test will generate and analyze a dummy crate using the stable mir.
|
||||
/// For that, it will first write the dummy crate into a file.
|
||||
/// Then it will create a `StableMir` using custom arguments and then
|
||||
|
64
tests/ui-fulldeps/stable-mir/smir_internal.rs
Normal file
64
tests/ui-fulldeps/stable-mir/smir_internal.rs
Normal file
@ -0,0 +1,64 @@
|
||||
// run-pass
|
||||
//! Test that users are able to use retrieve internal constructs from stable ones to help with
|
||||
//! the migration.
|
||||
|
||||
// ignore-stage1
|
||||
// ignore-cross-compile
|
||||
// ignore-remote
|
||||
// ignore-windows-gnu mingw has troubles with linking https://github.com/rust-lang/rust/pull/116837
|
||||
// edition: 2021
|
||||
|
||||
#![feature(rustc_private)]
|
||||
#![feature(assert_matches)]
|
||||
#![feature(control_flow_enum)]
|
||||
|
||||
#[macro_use]
|
||||
extern crate rustc_smir;
|
||||
extern crate rustc_driver;
|
||||
extern crate rustc_interface;
|
||||
extern crate rustc_middle;
|
||||
extern crate stable_mir;
|
||||
|
||||
use rustc_middle::ty::TyCtxt;
|
||||
use rustc_smir::rustc_internal;
|
||||
use std::io::Write;
|
||||
use std::ops::ControlFlow;
|
||||
|
||||
const CRATE_NAME: &str = "input";
|
||||
|
||||
fn test_translation(_tcx: TyCtxt<'_>) -> ControlFlow<()> {
|
||||
let main_fn = stable_mir::entry_fn().unwrap();
|
||||
let body = main_fn.body();
|
||||
let orig_ty = body.locals[0].ty;
|
||||
let rustc_ty = rustc_internal::internal(&orig_ty);
|
||||
assert!(rustc_ty.is_unit());
|
||||
ControlFlow::Continue(())
|
||||
}
|
||||
|
||||
/// This test will generate and analyze a dummy crate using the stable mir.
|
||||
/// For that, it will first write the dummy crate into a file.
|
||||
/// Then it will create a `StableMir` using custom arguments and then
|
||||
/// it will run the compiler.
|
||||
fn main() {
|
||||
let path = "internal_input.rs";
|
||||
generate_input(&path).unwrap();
|
||||
let args = vec![
|
||||
"rustc".to_string(),
|
||||
"--crate-name".to_string(),
|
||||
CRATE_NAME.to_string(),
|
||||
path.to_string(),
|
||||
];
|
||||
run!(args, tcx, test_translation(tcx)).unwrap();
|
||||
}
|
||||
|
||||
fn generate_input(path: &str) -> std::io::Result<()> {
|
||||
let mut file = std::fs::File::create(path)?;
|
||||
write!(
|
||||
file,
|
||||
r#"
|
||||
pub fn main() {{
|
||||
}}
|
||||
"#
|
||||
)?;
|
||||
Ok(())
|
||||
}
|
@ -30,6 +30,7 @@
|
||||
// revisions: loongarch64
|
||||
//[loongarch64] compile-flags: --target loongarch64-unknown-linux-gnu
|
||||
//[loongarch64] needs-llvm-components: loongarch
|
||||
//[loongarch64] min-llvm-version: 17
|
||||
// revisions: wasm
|
||||
//[wasm] compile-flags: --target wasm32-unknown-unknown
|
||||
//[wasm] needs-llvm-components: webassembly
|
||||
|
@ -1,7 +1,5 @@
|
||||
// edition: 2021
|
||||
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
use std::future::Future;
|
||||
use std::pin::Pin;
|
||||
|
||||
|
@ -1,11 +1,11 @@
|
||||
error[E0053]: method `foo` has an incompatible type for trait
|
||||
--> $DIR/async-example-desugared-boxed-in-trait.rs:13:5
|
||||
--> $DIR/async-example-desugared-boxed-in-trait.rs:11:5
|
||||
|
|
||||
LL | async fn foo(&self) -> i32 {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Pin<Box<dyn Future<Output = i32>>>`, found future
|
||||
|
|
||||
note: type in trait
|
||||
--> $DIR/async-example-desugared-boxed-in-trait.rs:9:22
|
||||
--> $DIR/async-example-desugared-boxed-in-trait.rs:7:22
|
||||
|
|
||||
LL | fn foo(&self) -> Pin<Box<dyn Future<Output = i32> + '_>>;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
@ -1,7 +1,5 @@
|
||||
// edition: 2021
|
||||
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
use std::future::Future;
|
||||
use std::pin::Pin;
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
error: method `foo` should be async because the method from the trait is async
|
||||
--> $DIR/async-example-desugared-boxed.rs:13:5
|
||||
--> $DIR/async-example-desugared-boxed.rs:11:5
|
||||
|
|
||||
LL | async fn foo(&self) -> i32;
|
||||
| --------------------------- required because the trait method is async
|
||||
|
@ -2,7 +2,6 @@
|
||||
// edition: 2021
|
||||
|
||||
#![feature(lint_reasons)]
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
use std::future::Future;
|
||||
use std::pin::Pin;
|
||||
|
@ -1,8 +1,6 @@
|
||||
// check-pass
|
||||
// edition: 2021
|
||||
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
use std::future::Future;
|
||||
|
||||
trait MyTrait {
|
||||
|
@ -1,7 +1,5 @@
|
||||
// edition: 2021
|
||||
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
use std::future::Future;
|
||||
use std::task::Poll;
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
error: method `foo` should be async because the method from the trait is async
|
||||
--> $DIR/async-example-desugared-manual.rs:21:5
|
||||
--> $DIR/async-example-desugared-manual.rs:19:5
|
||||
|
|
||||
LL | async fn foo(&self) -> i32;
|
||||
| --------------------------- required because the trait method is async
|
||||
|
@ -1,8 +1,6 @@
|
||||
// check-pass
|
||||
// edition: 2021
|
||||
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
use std::future::Future;
|
||||
|
||||
trait MyTrait {
|
||||
|
@ -1,8 +1,6 @@
|
||||
// check-pass
|
||||
// edition: 2021
|
||||
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
trait MyTrait {
|
||||
#[allow(async_fn_in_trait)]
|
||||
async fn foo(&self) -> i32;
|
||||
|
@ -2,8 +2,6 @@
|
||||
// known-bug: #102682
|
||||
// edition: 2021
|
||||
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
use std::fmt::Debug;
|
||||
use std::hash::Hash;
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
error[E0311]: the parameter type `U` may not live long enough
|
||||
--> $DIR/async-generics-and-bounds.rs:11:5
|
||||
--> $DIR/async-generics-and-bounds.rs:9:5
|
||||
|
|
||||
LL | async fn foo(&self) -> &(T, U) where T: Debug + Sized, U: Hash;
|
||||
| ^^^^^^^^^^^^^-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
@ -13,7 +13,7 @@ LL | async fn foo<'a>(&'a self) -> &'a (T, U) where T: Debug + Sized, U: Has
|
||||
| ++++ ++ ++ +++++++
|
||||
|
||||
error[E0311]: the parameter type `T` may not live long enough
|
||||
--> $DIR/async-generics-and-bounds.rs:11:5
|
||||
--> $DIR/async-generics-and-bounds.rs:9:5
|
||||
|
|
||||
LL | async fn foo(&self) -> &(T, U) where T: Debug + Sized, U: Hash;
|
||||
| ^^^^^^^^^^^^^-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
@ -2,8 +2,6 @@
|
||||
// known-bug: #102682
|
||||
// edition: 2021
|
||||
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
trait MyTrait<T, U> {
|
||||
async fn foo(&self) -> &(T, U);
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
error[E0311]: the parameter type `U` may not live long enough
|
||||
--> $DIR/async-generics.rs:8:5
|
||||
--> $DIR/async-generics.rs:6:5
|
||||
|
|
||||
LL | async fn foo(&self) -> &(T, U);
|
||||
| ^^^^^^^^^^^^^-^^^^^^^^^^^^^^^^^
|
||||
@ -13,7 +13,7 @@ LL | async fn foo<'a>(&'a self) -> &'a (T, U) where U: 'a;
|
||||
| ++++ ++ ++ +++++++++++
|
||||
|
||||
error[E0311]: the parameter type `T` may not live long enough
|
||||
--> $DIR/async-generics.rs:8:5
|
||||
--> $DIR/async-generics.rs:6:5
|
||||
|
|
||||
LL | async fn foo(&self) -> &(T, U);
|
||||
| ^^^^^^^^^^^^^-^^^^^^^^^^^^^^^^^
|
||||
|
@ -1,8 +1,6 @@
|
||||
// check-pass
|
||||
// edition: 2021
|
||||
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
use std::fmt::Debug;
|
||||
|
||||
trait MyTrait<'a, 'b, T> {
|
||||
|
@ -1,8 +1,6 @@
|
||||
// check-pass
|
||||
// edition: 2021
|
||||
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
trait MyTrait<'a, 'b, T> {
|
||||
#[allow(async_fn_in_trait)]
|
||||
async fn foo(&'a self, key: &'b T) -> (&'a Self, &'b T);
|
||||
|
@ -1,7 +1,5 @@
|
||||
// edition: 2021
|
||||
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
trait MyTrait<T> {
|
||||
async fn foo_recursive(&self, n: usize) -> T;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
error[E0733]: recursion in an `async fn` requires boxing
|
||||
--> $DIR/async-recursive-generic.rs:10:5
|
||||
--> $DIR/async-recursive-generic.rs:8:5
|
||||
|
|
||||
LL | async fn foo_recursive(&self, n: usize) -> T {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ recursive `async fn`
|
||||
|
@ -1,7 +1,5 @@
|
||||
// edition: 2021
|
||||
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
trait MyTrait {
|
||||
async fn foo_recursive(&self, n: usize) -> i32;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
error[E0733]: recursion in an `async fn` requires boxing
|
||||
--> $DIR/async-recursive.rs:10:5
|
||||
--> $DIR/async-recursive.rs:8:5
|
||||
|
|
||||
LL | async fn foo_recursive(&self, n: usize) -> i32 {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ recursive `async fn`
|
||||
|
@ -1,8 +1,6 @@
|
||||
// check-pass
|
||||
// edition:2021
|
||||
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
pub trait Foo {
|
||||
#[allow(async_fn_in_trait)]
|
||||
async fn foo(&mut self);
|
||||
|
@ -1,5 +1,3 @@
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
struct Wrapper<T>(T);
|
||||
|
||||
trait Foo {
|
||||
|
@ -1,5 +1,5 @@
|
||||
error[E0053]: method `bar` has an incompatible return type for trait
|
||||
--> $DIR/deep-match.rs:10:17
|
||||
--> $DIR/deep-match.rs:8:17
|
||||
|
|
||||
LL | fn bar() -> i32 {
|
||||
| ^^^
|
||||
|
@ -1,5 +1,3 @@
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
use std::ops::Deref;
|
||||
|
||||
pub trait Foo {
|
||||
|
@ -1,5 +1,5 @@
|
||||
error[E0271]: type mismatch resolving `<&i32 as Deref>::Target == String`
|
||||
--> $DIR/default-body-type-err.rs:6:22
|
||||
--> $DIR/default-body-type-err.rs:4:22
|
||||
|
|
||||
LL | fn lol(&self) -> impl Deref<Target = String> {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `i32`, found `String`
|
||||
|
@ -1,5 +1,3 @@
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
trait Foo {
|
||||
fn bar() -> impl std::fmt::Display;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
error[E0277]: `()` doesn't implement `std::fmt::Display`
|
||||
--> $DIR/doesnt-satisfy.rs:8:17
|
||||
--> $DIR/doesnt-satisfy.rs:6:17
|
||||
|
|
||||
LL | fn bar() -> () {}
|
||||
| ^^ `()` cannot be formatted with the default formatter
|
||||
@ -7,7 +7,7 @@ LL | fn bar() -> () {}
|
||||
= help: the trait `std::fmt::Display` is not implemented for `()`
|
||||
= note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
|
||||
note: required by a bound in `Foo::{opaque#0}`
|
||||
--> $DIR/doesnt-satisfy.rs:4:22
|
||||
--> $DIR/doesnt-satisfy.rs:2:22
|
||||
|
|
||||
LL | fn bar() -> impl std::fmt::Display;
|
||||
| ^^^^^^^^^^^^^^^^^ required by this bound in `Foo::{opaque#0}`
|
||||
|
@ -1,5 +1,3 @@
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
struct U;
|
||||
|
||||
trait Foo {
|
||||
|
@ -1,5 +1,5 @@
|
||||
error[E0049]: method `bar` has 1 type parameter but its trait declaration has 0 type parameters
|
||||
--> $DIR/generics-mismatch.rs:10:12
|
||||
--> $DIR/generics-mismatch.rs:8:12
|
||||
|
|
||||
LL | fn bar(&self) -> impl Sized;
|
||||
| - expected 0 type parameters
|
||||
|
@ -1,5 +1,3 @@
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
trait Marker {}
|
||||
impl Marker for u32 {}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
error[E0277]: the trait bound `&dyn MyTrait: MyTrait` is not satisfied
|
||||
--> $DIR/issue-102140.rs:22:22
|
||||
--> $DIR/issue-102140.rs:20:22
|
||||
|
|
||||
LL | MyTrait::foo(&self)
|
||||
| ------------ ^^^^^ the trait `MyTrait` is not implemented for `&dyn MyTrait`
|
||||
@ -13,7 +13,7 @@ LL + MyTrait::foo(self)
|
||||
|
|
||||
|
||||
error[E0277]: the trait bound `&dyn MyTrait: MyTrait` is not satisfied
|
||||
--> $DIR/issue-102140.rs:22:9
|
||||
--> $DIR/issue-102140.rs:20:9
|
||||
|
|
||||
LL | MyTrait::foo(&self)
|
||||
| ^^^^^^^^^^^^^^^^^^^ the trait `MyTrait` is not implemented for `&dyn MyTrait`
|
||||
@ -21,7 +21,7 @@ LL | MyTrait::foo(&self)
|
||||
= help: the trait `MyTrait` is implemented for `Outer`
|
||||
|
||||
error[E0277]: the trait bound `&dyn MyTrait: MyTrait` is not satisfied
|
||||
--> $DIR/issue-102140.rs:22:9
|
||||
--> $DIR/issue-102140.rs:20:9
|
||||
|
|
||||
LL | MyTrait::foo(&self)
|
||||
| ^^^^^^^^^^^^ the trait `MyTrait` is not implemented for `&dyn MyTrait`
|
||||
|
@ -1,5 +1,3 @@
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
use std::fmt::Display;
|
||||
use std::ops::Deref;
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/issue-102571.rs:11:9
|
||||
--> $DIR/issue-102571.rs:9:9
|
||||
|
|
||||
LL | let () = t.bar();
|
||||
| ^^ ------- this expression has type `impl Deref<Target = impl std::fmt::Display + ?Sized>`
|
||||
|
@ -1,5 +1,3 @@
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
use std::fmt::Debug;
|
||||
|
||||
trait Foo {
|
||||
|
@ -1,11 +1,11 @@
|
||||
error[E0038]: the trait `Foo` cannot be made into an object
|
||||
--> $DIR/object-safety.rs:16:33
|
||||
--> $DIR/object-safety.rs:14:33
|
||||
|
|
||||
LL | let i = Box::new(42_u32) as Box<dyn Foo>;
|
||||
| ^^^^^^^^^^^^ `Foo` cannot be made into an object
|
||||
|
|
||||
note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
|
||||
--> $DIR/object-safety.rs:6:22
|
||||
--> $DIR/object-safety.rs:4:22
|
||||
|
|
||||
LL | trait Foo {
|
||||
| --- this trait cannot be made into an object...
|
||||
@ -14,13 +14,13 @@ LL | fn baz(&self) -> impl Debug;
|
||||
= help: consider moving `baz` to another trait
|
||||
|
||||
error[E0038]: the trait `Foo` cannot be made into an object
|
||||
--> $DIR/object-safety.rs:19:15
|
||||
--> $DIR/object-safety.rs:17:15
|
||||
|
|
||||
LL | let s = i.baz();
|
||||
| ^^^ `Foo` cannot be made into an object
|
||||
|
|
||||
note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
|
||||
--> $DIR/object-safety.rs:6:22
|
||||
--> $DIR/object-safety.rs:4:22
|
||||
|
|
||||
LL | trait Foo {
|
||||
| --- this trait cannot be made into an object...
|
||||
@ -29,13 +29,13 @@ LL | fn baz(&self) -> impl Debug;
|
||||
= help: consider moving `baz` to another trait
|
||||
|
||||
error[E0038]: the trait `Foo` cannot be made into an object
|
||||
--> $DIR/object-safety.rs:19:13
|
||||
--> $DIR/object-safety.rs:17:13
|
||||
|
|
||||
LL | let s = i.baz();
|
||||
| ^^^^^^^ `Foo` cannot be made into an object
|
||||
|
|
||||
note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
|
||||
--> $DIR/object-safety.rs:6:22
|
||||
--> $DIR/object-safety.rs:4:22
|
||||
|
|
||||
LL | trait Foo {
|
||||
| --- this trait cannot be made into an object...
|
||||
@ -44,13 +44,13 @@ LL | fn baz(&self) -> impl Debug;
|
||||
= help: consider moving `baz` to another trait
|
||||
|
||||
error[E0038]: the trait `Foo` cannot be made into an object
|
||||
--> $DIR/object-safety.rs:16:13
|
||||
--> $DIR/object-safety.rs:14:13
|
||||
|
|
||||
LL | let i = Box::new(42_u32) as Box<dyn Foo>;
|
||||
| ^^^^^^^^^^^^^^^^ `Foo` cannot be made into an object
|
||||
|
|
||||
note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
|
||||
--> $DIR/object-safety.rs:6:22
|
||||
--> $DIR/object-safety.rs:4:22
|
||||
|
|
||||
LL | trait Foo {
|
||||
| --- this trait cannot be made into an object...
|
||||
|
@ -1,5 +1,3 @@
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
use std::fmt::Display;
|
||||
|
||||
trait Foo {
|
||||
|
@ -1,5 +1,5 @@
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/opaque-in-impl-is-opaque.rs:16:19
|
||||
--> $DIR/opaque-in-impl-is-opaque.rs:14:19
|
||||
|
|
||||
LL | fn bar(&self) -> impl Display {
|
||||
| ------------ the found opaque type
|
||||
|
@ -1,5 +1,3 @@
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
struct S;
|
||||
|
||||
trait Foo {
|
||||
|
@ -1,5 +1,5 @@
|
||||
error[E0049]: method `bar` has 0 type parameters but its trait declaration has 1 type parameter
|
||||
--> $DIR/trait-more-generics-than-impl.rs:10:11
|
||||
--> $DIR/trait-more-generics-than-impl.rs:8:11
|
||||
|
|
||||
LL | fn bar<T>() -> impl Sized;
|
||||
| - expected 1 type parameter
|
||||
|
@ -1,2 +1,2 @@
|
||||
error: incorrect value `bad-value` for codegen option `instrument-coverage` - `all` (default), `except-unused-generics`, `except-unused-functions`, or `off` was expected
|
||||
error: incorrect value `bad-value` for codegen option `instrument-coverage` - `all` (default), `branch`, `except-unused-generics`, `except-unused-functions`, or `off` was expected
|
||||
|
||||
|
@ -1,2 +1,2 @@
|
||||
error: incorrect value `` for codegen option `instrument-coverage` - `all` (default), `except-unused-generics`, `except-unused-functions`, or `off` was expected
|
||||
error: incorrect value `` for codegen option `instrument-coverage` - `all` (default), `branch`, `except-unused-generics`, `except-unused-functions`, or `off` was expected
|
||||
|
||||
|
@ -1,2 +1,2 @@
|
||||
error: `-C instrument-coverage=except-*` requires `-Z unstable-options`
|
||||
error: `-C instrument-coverage=branch` and `-C instrument-coverage=except-*` require `-Z unstable-options`
|
||||
|
||||
|
@ -1,2 +1,2 @@
|
||||
error: `-C instrument-coverage=except-*` requires `-Z unstable-options`
|
||||
error: `-C instrument-coverage=branch` and `-C instrument-coverage=except-*` require `-Z unstable-options`
|
||||
|
||||
|
@ -44,6 +44,10 @@ LL | fn parse_type(iter: Box<dyn Iterator<Item=&str>+'static>) -> &str { iter.ne
|
||||
|
|
||||
= note: expected reference `&str`
|
||||
found enum `Option<&str>`
|
||||
help: consider using `Option::expect` to unwrap the `Option<&str>` value, panicking if the value is an `Option::None`
|
||||
|
|
||||
LL | fn parse_type(iter: Box<dyn Iterator<Item=&str>+'static>) -> &str { iter.next().expect("REASON") }
|
||||
| +++++++++++++++++
|
||||
|
||||
error[E0061]: this function takes 1 argument but 0 arguments were supplied
|
||||
--> $DIR/issue-26638.rs:5:47
|
||||
|
23
tests/ui/mismatched_types/mismatch-ty-dont-suggest.rs
Normal file
23
tests/ui/mismatched_types/mismatch-ty-dont-suggest.rs
Normal file
@ -0,0 +1,23 @@
|
||||
#![allow(unused, dead_code)]
|
||||
|
||||
fn test_unwrap() -> Option<i32> {
|
||||
let b: Result<i32, ()> = Ok(1);
|
||||
let v: i32 = b; // return type is not `Result`, we don't suggest ? here
|
||||
//~^ ERROR mismatched types
|
||||
Some(v)
|
||||
}
|
||||
|
||||
fn test_unwrap_option() -> Result<i32, ()> {
|
||||
let b = Some(1);
|
||||
let v: i32 = b; // return type is not `Option`, we don't suggest ? here
|
||||
//~^ ERROR mismatched types
|
||||
Ok(v)
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let v: i32 = Some(0); //~ ERROR mismatched types
|
||||
|
||||
let c = Ok(false);
|
||||
let v: i32 = c; //~ ERROR mismatched types
|
||||
|
||||
}
|
55
tests/ui/mismatched_types/mismatch-ty-dont-suggest.stderr
Normal file
55
tests/ui/mismatched_types/mismatch-ty-dont-suggest.stderr
Normal file
@ -0,0 +1,55 @@
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/mismatch-ty-dont-suggest.rs:5:18
|
||||
|
|
||||
LL | let v: i32 = b; // return type is not `Result`, we don't suggest ? here
|
||||
| --- ^ expected `i32`, found `Result<i32, ()>`
|
||||
| |
|
||||
| expected due to this
|
||||
|
|
||||
= note: expected type `i32`
|
||||
found enum `Result<i32, ()>`
|
||||
help: consider using `Result::expect` to unwrap the `Result<i32, ()>` value, panicking if the value is a `Result::Err`
|
||||
|
|
||||
LL | let v: i32 = b.expect("REASON"); // return type is not `Result`, we don't suggest ? here
|
||||
| +++++++++++++++++
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/mismatch-ty-dont-suggest.rs:12:18
|
||||
|
|
||||
LL | let v: i32 = b; // return type is not `Option`, we don't suggest ? here
|
||||
| --- ^ expected `i32`, found `Option<{integer}>`
|
||||
| |
|
||||
| expected due to this
|
||||
|
|
||||
= note: expected type `i32`
|
||||
found enum `Option<{integer}>`
|
||||
help: consider using `Option::expect` to unwrap the `Option<{integer}>` value, panicking if the value is an `Option::None`
|
||||
|
|
||||
LL | let v: i32 = b.expect("REASON"); // return type is not `Option`, we don't suggest ? here
|
||||
| +++++++++++++++++
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/mismatch-ty-dont-suggest.rs:18:18
|
||||
|
|
||||
LL | let v: i32 = Some(0);
|
||||
| --- ^^^^^^^ expected `i32`, found `Option<{integer}>`
|
||||
| |
|
||||
| expected due to this
|
||||
|
|
||||
= note: expected type `i32`
|
||||
found enum `Option<{integer}>`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/mismatch-ty-dont-suggest.rs:21:18
|
||||
|
|
||||
LL | let v: i32 = c;
|
||||
| --- ^ expected `i32`, found `Result<bool, _>`
|
||||
| |
|
||||
| expected due to this
|
||||
|
|
||||
= note: expected type `i32`
|
||||
found enum `Result<bool, _>`
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0308`.
|
31
tests/ui/mismatched_types/mismatch-ty-unwrap-expect.fixed
Normal file
31
tests/ui/mismatched_types/mismatch-ty-unwrap-expect.fixed
Normal file
@ -0,0 +1,31 @@
|
||||
// run-rustfix
|
||||
#![allow(unused, dead_code)]
|
||||
|
||||
fn func() -> Option<i32> {
|
||||
Some(1)
|
||||
}
|
||||
|
||||
fn test_unwrap() -> Result<i32, ()> {
|
||||
let b: Result<i32, ()> = Ok(1);
|
||||
let v: i32 = b?; //~ ERROR mismatched types
|
||||
Ok(v)
|
||||
}
|
||||
|
||||
fn test_unwrap_option() -> Option<i32> {
|
||||
let b = Some(1);
|
||||
let v: i32 = b?; //~ ERROR mismatched types
|
||||
Some(v)
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let a = Some(1);
|
||||
let v: i32 = a.expect("REASON"); //~ ERROR mismatched types
|
||||
|
||||
let b: Result<i32, ()> = Ok(1);
|
||||
let v: i32 = b.expect("REASON"); //~ ERROR mismatched types
|
||||
|
||||
let v: i32 = func().expect("REASON"); //~ ERROR mismatched types
|
||||
|
||||
let a = None;
|
||||
let v: i32 = a.expect("REASON"); //~ ERROR mismatched types
|
||||
}
|
31
tests/ui/mismatched_types/mismatch-ty-unwrap-expect.rs
Normal file
31
tests/ui/mismatched_types/mismatch-ty-unwrap-expect.rs
Normal file
@ -0,0 +1,31 @@
|
||||
// run-rustfix
|
||||
#![allow(unused, dead_code)]
|
||||
|
||||
fn func() -> Option<i32> {
|
||||
Some(1)
|
||||
}
|
||||
|
||||
fn test_unwrap() -> Result<i32, ()> {
|
||||
let b: Result<i32, ()> = Ok(1);
|
||||
let v: i32 = b; //~ ERROR mismatched types
|
||||
Ok(v)
|
||||
}
|
||||
|
||||
fn test_unwrap_option() -> Option<i32> {
|
||||
let b = Some(1);
|
||||
let v: i32 = b; //~ ERROR mismatched types
|
||||
Some(v)
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let a = Some(1);
|
||||
let v: i32 = a; //~ ERROR mismatched types
|
||||
|
||||
let b: Result<i32, ()> = Ok(1);
|
||||
let v: i32 = b; //~ ERROR mismatched types
|
||||
|
||||
let v: i32 = func(); //~ ERROR mismatched types
|
||||
|
||||
let a = None;
|
||||
let v: i32 = a; //~ ERROR mismatched types
|
||||
}
|
93
tests/ui/mismatched_types/mismatch-ty-unwrap-expect.stderr
Normal file
93
tests/ui/mismatched_types/mismatch-ty-unwrap-expect.stderr
Normal file
@ -0,0 +1,93 @@
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/mismatch-ty-unwrap-expect.rs:10:18
|
||||
|
|
||||
LL | let v: i32 = b;
|
||||
| --- ^ expected `i32`, found `Result<i32, ()>`
|
||||
| |
|
||||
| expected due to this
|
||||
|
|
||||
= note: expected type `i32`
|
||||
found enum `Result<i32, ()>`
|
||||
help: use the `?` operator to extract the `Result<i32, ()>` value, propagating a `Result::Err` value to the caller
|
||||
|
|
||||
LL | let v: i32 = b?;
|
||||
| +
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/mismatch-ty-unwrap-expect.rs:16:18
|
||||
|
|
||||
LL | let v: i32 = b;
|
||||
| --- ^ expected `i32`, found `Option<{integer}>`
|
||||
| |
|
||||
| expected due to this
|
||||
|
|
||||
= note: expected type `i32`
|
||||
found enum `Option<{integer}>`
|
||||
help: use the `?` operator to extract the `Option<{integer}>` value, propagating an `Option::None` value to the caller
|
||||
|
|
||||
LL | let v: i32 = b?;
|
||||
| +
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/mismatch-ty-unwrap-expect.rs:22:18
|
||||
|
|
||||
LL | let v: i32 = a;
|
||||
| --- ^ expected `i32`, found `Option<{integer}>`
|
||||
| |
|
||||
| expected due to this
|
||||
|
|
||||
= note: expected type `i32`
|
||||
found enum `Option<{integer}>`
|
||||
help: consider using `Option::expect` to unwrap the `Option<{integer}>` value, panicking if the value is an `Option::None`
|
||||
|
|
||||
LL | let v: i32 = a.expect("REASON");
|
||||
| +++++++++++++++++
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/mismatch-ty-unwrap-expect.rs:25:18
|
||||
|
|
||||
LL | let v: i32 = b;
|
||||
| --- ^ expected `i32`, found `Result<i32, ()>`
|
||||
| |
|
||||
| expected due to this
|
||||
|
|
||||
= note: expected type `i32`
|
||||
found enum `Result<i32, ()>`
|
||||
help: consider using `Result::expect` to unwrap the `Result<i32, ()>` value, panicking if the value is a `Result::Err`
|
||||
|
|
||||
LL | let v: i32 = b.expect("REASON");
|
||||
| +++++++++++++++++
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/mismatch-ty-unwrap-expect.rs:27:18
|
||||
|
|
||||
LL | let v: i32 = func();
|
||||
| --- ^^^^^^ expected `i32`, found `Option<i32>`
|
||||
| |
|
||||
| expected due to this
|
||||
|
|
||||
= note: expected type `i32`
|
||||
found enum `Option<i32>`
|
||||
help: consider using `Option::expect` to unwrap the `Option<i32>` value, panicking if the value is an `Option::None`
|
||||
|
|
||||
LL | let v: i32 = func().expect("REASON");
|
||||
| +++++++++++++++++
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/mismatch-ty-unwrap-expect.rs:30:18
|
||||
|
|
||||
LL | let v: i32 = a;
|
||||
| --- ^ expected `i32`, found `Option<_>`
|
||||
| |
|
||||
| expected due to this
|
||||
|
|
||||
= note: expected type `i32`
|
||||
found enum `Option<_>`
|
||||
help: consider using `Option::expect` to unwrap the `Option<_>` value, panicking if the value is an `Option::None`
|
||||
|
|
||||
LL | let v: i32 = a.expect("REASON");
|
||||
| +++++++++++++++++
|
||||
|
||||
error: aborting due to 6 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0308`.
|
@ -8,6 +8,10 @@ LL | let x: isize = noexporttypelib::foo();
|
||||
|
|
||||
= note: expected type `isize`
|
||||
found enum `Option<isize>`
|
||||
help: consider using `Option::expect` to unwrap the `Option<isize>` value, panicking if the value is an `Option::None`
|
||||
|
|
||||
LL | let x: isize = noexporttypelib::foo().expect("REASON");
|
||||
| +++++++++++++++++
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -18,6 +18,7 @@
|
||||
// gate-test-bpf_target_feature
|
||||
// gate-test-aarch64_ver_target_feature
|
||||
// gate-test-csky_target_feature
|
||||
// gate-test-loongarch_target_feature
|
||||
|
||||
#[target_feature(enable = "avx512bw")]
|
||||
//~^ ERROR: currently unstable
|
||||
|
@ -1,5 +1,5 @@
|
||||
error[E0658]: the target feature `avx512bw` is currently unstable
|
||||
--> $DIR/gate.rs:22:18
|
||||
--> $DIR/gate.rs:23:18
|
||||
|
|
||||
LL | #[target_feature(enable = "avx512bw")]
|
||||
| ^^^^^^^^^^^^^^^^^^^
|
||||
|
@ -8,6 +8,10 @@ LL | let x : char = last(y);
|
||||
|
|
||||
= note: expected type `char`
|
||||
found enum `Option<_>`
|
||||
help: consider using `Option::expect` to unwrap the `Option<_>` value, panicking if the value is an `Option::None`
|
||||
|
|
||||
LL | let x : char = last(y).expect("REASON");
|
||||
| +++++++++++++++++
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user