Auto merge of #126374 - workingjubilee:rollup-tz0utfr, r=workingjubilee

Rollup of 10 pull requests

Successful merges:

 - #125674 (Rewrite `symlinked-extern`, `symlinked-rlib` and `symlinked-libraries` `run-make` tests in `rmake.rs` format)
 - #125688 (Walk into alias-eq nested goals even if normalization fails)
 - #126142 (Harmonize using root or leaf obligation in trait error reporting)
 - #126303 (Urls to docs in rust_hir)
 - #126328 (Add Option::is_none_or)
 - #126337 (Add test for walking order dependent opaque type behaviour)
 - #126353 (Move `MatchAgainstFreshVars` to old solver)
 - #126356 (docs(rustc): Improve discoverable of Cargo docs)
 - #126358 (safe transmute: support `Single` enums)
 - #126362 (Make `try_from_target_usize` method public)

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2024-06-13 05:00:13 +00:00
commit 56e112afb6
80 changed files with 557 additions and 275 deletions

View File

@ -241,10 +241,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
variant_index: VariantIdx,
) -> InterpResult<'tcx, Option<(ScalarInt, usize)>> {
match self.layout_of(ty)?.variants {
abi::Variants::Single { index } => {
assert_eq!(index, variant_index);
Ok(None)
}
abi::Variants::Single { .. } => Ok(None),
abi::Variants::Multiple {
tag_encoding: TagEncoding::Direct,

View File

@ -1057,7 +1057,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
ty::Str | ty::Slice(_) | ty::Dynamic(_, _, ty::Dyn) | ty::Foreign(..) => false,
ty::Tuple(tys) => tys.last().iter().all(|ty| is_very_trivially_sized(**ty)),
ty::Tuple(tys) => tys.last().is_none_or(|ty| is_very_trivially_sized(*ty)),
ty::Pat(ty, ..) => is_very_trivially_sized(*ty),

View File

@ -446,7 +446,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
let (alloc_size, _alloc_align, ret_val) = alloc_size(alloc_id, offset, prov)?;
// Test bounds.
// It is sufficient to check this for the end pointer. Also check for overflow!
if offset.checked_add(size, &self.tcx).map_or(true, |end| end > alloc_size) {
if offset.checked_add(size, &self.tcx).is_none_or(|end| end > alloc_size) {
throw_ub!(PointerOutOfBounds {
alloc_id,
alloc_size,

View File

@ -300,7 +300,7 @@ where
) -> InterpResult<'tcx, P> {
let len = base.len(self)?; // also asserts that we have a type where this makes sense
let actual_to = if from_end {
if from.checked_add(to).map_or(true, |to| to > len) {
if from.checked_add(to).is_none_or(|to| to > len) {
// This can only be reached in ConstProp and non-rustc-MIR.
throw_ub!(BoundsCheckFailed { len: len, index: from.saturating_add(to) });
}

View File

@ -6,6 +6,7 @@
#![feature(box_patterns)]
#![feature(decl_macro)]
#![feature(if_let_guard)]
#![feature(is_none_or)]
#![feature(let_chains)]
#![feature(never_type)]
#![feature(rustdoc_internals)]

View File

@ -1633,6 +1633,13 @@ pub struct ConstBlock {
}
/// An expression.
///
/// For more details, see the [rust lang reference].
/// Note that the reference does not document nightly-only features.
/// There may be also slight differences in the names and representation of AST nodes between
/// the compiler and the reference.
///
/// [rust lang reference]: https://doc.rust-lang.org/reference/expressions.html
#[derive(Debug, Clone, Copy, HashStable_Generic)]
pub struct Expr<'hir> {
pub hir_id: HirId,
@ -3147,6 +3154,13 @@ impl ItemId {
/// An item
///
/// The name might be a dummy name in case of anonymous items
///
/// For more details, see the [rust lang reference].
/// Note that the reference does not document nightly-only features.
/// There may be also slight differences in the names and representation of AST nodes between
/// the compiler and the reference.
///
/// [rust lang reference]: https://doc.rust-lang.org/reference/items.html
#[derive(Debug, Clone, Copy, HashStable_Generic)]
pub struct Item<'hir> {
pub ident: Ident,

View File

@ -234,7 +234,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let ret_ty = ret_coercion.borrow().expected_ty();
let ret_ty = self.infcx.shallow_resolve(ret_ty);
self.can_coerce(arm_ty, ret_ty)
&& prior_arm.map_or(true, |(_, ty, _)| self.can_coerce(ty, ret_ty))
&& prior_arm.is_none_or(|(_, ty, _)| self.can_coerce(ty, ret_ty))
// The match arms need to unify for the case of `impl Trait`.
&& !matches!(ret_ty.kind(), ty::Alias(ty::Opaque, ..))
}

View File

@ -913,7 +913,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
if self
.tcx
.upvars_mentioned(closure_def_id_a.expect_local())
.map_or(true, |u| u.is_empty()) =>
.is_none_or(|u| u.is_empty()) =>
{
// We coerce the closure, which has fn type
// `extern "rust-call" fn((arg0,arg1,...)) -> _`

View File

@ -1557,7 +1557,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// If the length is 0, we don't create any elements, so we don't copy any. If the length is 1, we
// don't copy that one element, we move it. Only check for Copy if the length is larger.
if count.try_eval_target_usize(tcx, self.param_env).map_or(true, |len| len > 1) {
if count.try_eval_target_usize(tcx, self.param_env).is_none_or(|len| len > 1) {
let lang_item = self.tcx.require_lang_item(LangItem::Copy, None);
let code = traits::ObligationCauseCode::RepeatElementCopy {
is_constable,

View File

@ -2240,7 +2240,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
for (idx, (generic_param, param)) in
params_with_generics.iter().enumerate().filter(|(idx, _)| {
check_for_matched_generics
|| expected_idx.map_or(true, |expected_idx| expected_idx == *idx)
|| expected_idx.is_none_or(|expected_idx| expected_idx == *idx)
})
{
let Some(generic_param) = generic_param else {

View File

@ -440,7 +440,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
};
// Given `Result<_, E>`, check our expected ty is `Result<_, &E>` for
// `as_ref` and `as_deref` compatibility.
let error_tys_equate_as_ref = error_tys.map_or(true, |(found, expected)| {
let error_tys_equate_as_ref = error_tys.is_none_or(|(found, expected)| {
self.can_eq(
self.param_env,
Ty::new_imm_ref(self.tcx, self.tcx.lifetimes.re_erased, found),
@ -492,7 +492,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
&& Some(adt.did()) == self.tcx.lang_items().string()
&& peeled.is_str()
// `Result::map`, conversely, does not take ref of the error type.
&& error_tys.map_or(true, |(found, expected)| {
&& error_tys.is_none_or(|(found, expected)| {
self.can_eq(self.param_env, found, expected)
})
{

View File

@ -4,6 +4,7 @@
#![feature(box_patterns)]
#![feature(control_flow_enum)]
#![feature(if_let_guard)]
#![feature(is_none_or)]
#![feature(let_chains)]
#![feature(never_type)]
#![feature(try_blocks)]

View File

@ -546,7 +546,7 @@ impl<T> Trait<T> for X {
for pred in hir_generics.bounds_for_param(def_id) {
if self.constrain_generic_bound_associated_type_structured_suggestion(
diag,
&trait_ref,
trait_ref,
pred.bounds,
assoc,
assoc_args,
@ -715,7 +715,7 @@ fn foo(&self) -> Self::T { String::new() }
self.constrain_generic_bound_associated_type_structured_suggestion(
diag,
&trait_ref,
trait_ref,
opaque_hir_ty.bounds,
assoc,
assoc_args,
@ -869,7 +869,7 @@ fn foo(&self) -> Self::T { String::new() }
fn constrain_generic_bound_associated_type_structured_suggestion(
&self,
diag: &mut Diag<'_>,
trait_ref: &ty::TraitRef<'tcx>,
trait_ref: ty::TraitRef<'tcx>,
bounds: hir::GenericBounds<'_>,
assoc: ty::AssocItem,
assoc_args: &[ty::GenericArg<'tcx>],

View File

@ -4,11 +4,9 @@
pub use rustc_middle::ty::relate::*;
pub use self::_match::MatchAgainstFreshVars;
pub use self::combine::CombineFields;
pub use self::combine::PredicateEmittingRelation;
pub mod _match;
pub(super) mod combine;
mod generalize;
mod glb;

View File

@ -285,8 +285,7 @@ impl<'tcx, O: Elaboratable<'tcx>> Elaborator<'tcx, O> {
let obligations =
predicates.predicates.iter().enumerate().map(|(index, &(clause, span))| {
elaboratable.child_with_derived_cause(
clause
.instantiate_supertrait(tcx, &bound_clause.rebind(data.trait_ref)),
clause.instantiate_supertrait(tcx, bound_clause.rebind(data.trait_ref)),
span,
bound_clause.rebind(data),
index,

View File

@ -3257,7 +3257,11 @@ declare_lint! {
/// See the [Checking Conditional Configurations][check-cfg] section for more
/// details.
///
/// See the [Cargo Specifics][unexpected_cfgs_lint_config] section for configuring this lint in
/// `Cargo.toml`.
///
/// [check-cfg]: https://doc.rust-lang.org/nightly/rustc/check-cfg.html
/// [unexpected_cfgs_lint_config]: https://doc.rust-lang.org/nightly/rustc/check-cfg/cargo-specifics.html#check-cfg-in-lintsrust-table
pub UNEXPECTED_CFGS,
Warn,
"detects unexpected names and values in `#[cfg]` conditions",

View File

@ -37,7 +37,7 @@ impl<'tcx> Elaborator<'tcx> {
let super_predicates =
self.tcx.super_predicates_of(trait_ref.def_id()).predicates.iter().filter_map(
|&(pred, _)| {
let clause = pred.instantiate_supertrait(self.tcx, &trait_ref);
let clause = pred.instantiate_supertrait(self.tcx, trait_ref);
self.visited.insert(clause).then_some(clause)
},
);

View File

@ -313,7 +313,7 @@ impl<'tcx> Clause<'tcx> {
pub fn instantiate_supertrait(
self,
tcx: TyCtxt<'tcx>,
trait_ref: &ty::PolyTraitRef<'tcx>,
trait_ref: ty::PolyTraitRef<'tcx>,
) -> Clause<'tcx> {
// The interaction between HRTB and supertraits is not entirely
// obvious. Let me walk you (and myself) through an example.

View File

@ -48,6 +48,12 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
rhs
};
// Add a `make_canonical_response` probe step so that we treat this as
// a candidate, even if `try_evaluate_added_goals` bails due to an error.
// It's `Certainty::AMBIGUOUS` because this candidate is not "finished",
// since equating the normalized terms will lead to additional constraints.
self.inspect.make_canonical_response(Certainty::AMBIGUOUS);
// Apply the constraints.
self.try_evaluate_added_goals()?;
let lhs = self.resolve_vars_if_possible(lhs);

View File

@ -460,9 +460,10 @@ impl<'tcx> ProofTreeVisitor<'tcx> for BestObligation<'tcx> {
polarity: ty::PredicatePolarity::Positive,
}))
}
ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(_)) => {
ChildMode::WellFormedObligation
}
ty::PredicateKind::Clause(
ty::ClauseKind::WellFormed(_) | ty::ClauseKind::Projection(..),
)
| ty::PredicateKind::AliasRelate(..) => ChildMode::PassThrough,
_ => {
return ControlFlow::Break(self.obligation.clone());
}
@ -496,7 +497,7 @@ impl<'tcx> ProofTreeVisitor<'tcx> for BestObligation<'tcx> {
(_, GoalSource::InstantiateHigherRanked) => {
obligation = self.obligation.clone();
}
(ChildMode::WellFormedObligation, _) => {
(ChildMode::PassThrough, _) => {
obligation = make_obligation(self.obligation.cause.clone());
}
}
@ -527,7 +528,7 @@ enum ChildMode<'tcx> {
// Skip trying to derive an `ObligationCause` from this obligation, and
// report *all* sub-obligations as if they came directly from the parent
// obligation.
WellFormedObligation,
PassThrough,
}
fn derive_cause<'tcx>(

View File

@ -15,7 +15,7 @@ use rustc_infer::infer::{DefineOpaqueTypes, InferCtxt, InferOk};
use rustc_macros::extension;
use rustc_middle::traits::query::NoSolution;
use rustc_middle::traits::solve::{inspect, QueryResult};
use rustc_middle::traits::solve::{Certainty, Goal};
use rustc_middle::traits::solve::{Certainty, Goal, MaybeCause};
use rustc_middle::traits::ObligationCause;
use rustc_middle::ty::{TyCtxt, TypeFoldable};
use rustc_middle::{bug, ty};
@ -291,7 +291,10 @@ impl<'a, 'tcx> InspectGoal<'a, 'tcx> {
steps.push(step)
}
inspect::ProbeStep::MakeCanonicalResponse { shallow_certainty: c } => {
assert_eq!(shallow_certainty.replace(c), None);
assert!(matches!(
shallow_certainty.replace(c),
None | Some(Certainty::Maybe(MaybeCause::Ambiguity))
));
}
inspect::ProbeStep::NestedProbe(ref probe) => {
match probe.kind {

View File

@ -3597,7 +3597,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
&self,
obligation: &PredicateObligation<'tcx>,
err: &mut Diag<'_>,
trait_ref: &ty::PolyTraitRef<'tcx>,
trait_ref: ty::PolyTraitRef<'tcx>,
) {
let rhs_span = match obligation.cause.code() {
ObligationCauseCode::BinOp { rhs_span: Some(span), rhs_is_lit, .. } if *rhs_is_lit => {
@ -4592,7 +4592,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
&self,
obligation: &PredicateObligation<'tcx>,
err: &mut Diag<'_>,
trait_ref: ty::PolyTraitRef<'tcx>,
trait_pred: ty::PolyTraitPredicate<'tcx>,
) {
if ObligationCauseCode::QuestionMark != *obligation.cause.code().peel_derives() {
return;
@ -4602,10 +4602,9 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
if let hir::Node::Item(item) = node
&& let hir::ItemKind::Fn(sig, _, body_id) = item.kind
&& let hir::FnRetTy::DefaultReturn(ret_span) = sig.decl.output
&& self.tcx.is_diagnostic_item(sym::FromResidual, trait_ref.def_id())
&& let ty::Tuple(l) = trait_ref.skip_binder().args.type_at(0).kind()
&& l.len() == 0
&& let ty::Adt(def, _) = trait_ref.skip_binder().args.type_at(1).kind()
&& self.tcx.is_diagnostic_item(sym::FromResidual, trait_pred.def_id())
&& trait_pred.skip_binder().trait_ref.args.type_at(0).is_unit()
&& let ty::Adt(def, _) = trait_pred.skip_binder().trait_ref.args.type_at(1).kind()
&& self.tcx.is_diagnostic_item(sym::Result, def.did())
{
let body = self.tcx.hir().body(body_id);
@ -4863,14 +4862,13 @@ impl<'a, 'hir> hir::intravisit::Visitor<'hir> for ReplaceImplTraitVisitor<'a> {
pub(super) fn get_explanation_based_on_obligation<'tcx>(
tcx: TyCtxt<'tcx>,
obligation: &PredicateObligation<'tcx>,
trait_ref: ty::PolyTraitRef<'tcx>,
trait_predicate: &ty::PolyTraitPredicate<'tcx>,
trait_predicate: ty::PolyTraitPredicate<'tcx>,
pre_message: String,
) -> String {
if let ObligationCauseCode::MainFunctionType = obligation.cause.code() {
"consider using `()`, or a `Result`".to_owned()
} else {
let ty_desc = match trait_ref.skip_binder().self_ty().kind() {
let ty_desc = match trait_predicate.self_ty().skip_binder().kind() {
ty::FnDef(_, _) => Some("fn item"),
ty::Closure(_, _) => Some("closure"),
_ => None,
@ -4895,7 +4893,7 @@ pub(super) fn get_explanation_based_on_obligation<'tcx>(
format!(
"{pre_message}the trait `{}` is not implemented for{desc} `{}`{post}",
trait_predicate.print_modifiers_and_trait_path(),
tcx.short_ty_string(trait_ref.skip_binder().self_ty(), &mut None),
tcx.short_ty_string(trait_predicate.self_ty().skip_binder(), &mut None),
)
} else {
// "the trait bound `T: !Send` is not satisfied" reads better than "`!Send` is

View File

@ -412,8 +412,8 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
let bound_predicate = obligation.predicate.kind();
match bound_predicate.skip_binder() {
ty::PredicateKind::Clause(ty::ClauseKind::Trait(trait_predicate)) => {
let trait_predicate = bound_predicate.rebind(trait_predicate);
let trait_predicate = self.resolve_vars_if_possible(trait_predicate);
let leaf_trait_predicate =
self.resolve_vars_if_possible(bound_predicate.rebind(trait_predicate));
// Let's use the root obligation as the main message, when we care about the
// most general case ("X doesn't implement Pattern<'_>") over the case that
@ -424,7 +424,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
let (main_trait_predicate, o) = if let ty::PredicateKind::Clause(
ty::ClauseKind::Trait(root_pred)
) = root_obligation.predicate.kind().skip_binder()
&& !trait_predicate.self_ty().skip_binder().has_escaping_bound_vars()
&& !leaf_trait_predicate.self_ty().skip_binder().has_escaping_bound_vars()
&& !root_pred.self_ty().has_escaping_bound_vars()
// The type of the leaf predicate is (roughly) the same as the type
// from the root predicate, as a proxy for "we care about the root"
@ -434,20 +434,20 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
// `T: Trait` && `&&T: OtherTrait`, we want `OtherTrait`
self.can_eq(
obligation.param_env,
trait_predicate.self_ty().skip_binder(),
leaf_trait_predicate.self_ty().skip_binder(),
root_pred.self_ty().peel_refs(),
)
// `&str: Iterator` && `&str: IntoIterator`, we want `IntoIterator`
|| self.can_eq(
obligation.param_env,
trait_predicate.self_ty().skip_binder(),
leaf_trait_predicate.self_ty().skip_binder(),
root_pred.self_ty(),
)
)
// The leaf trait and the root trait are different, so as to avoid
// talking about `&mut T: Trait` and instead remain talking about
// `T: Trait` instead
&& trait_predicate.def_id() != root_pred.def_id()
&& leaf_trait_predicate.def_id() != root_pred.def_id()
// The root trait is not `Unsize`, as to avoid talking about it in
// `tests/ui/coercion/coerce-issue-49593-box-never.rs`.
&& Some(root_pred.def_id()) != self.tcx.lang_items().unsize_trait()
@ -459,13 +459,14 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
root_obligation,
)
} else {
(trait_predicate, &obligation)
(leaf_trait_predicate, &obligation)
};
let trait_ref = main_trait_predicate.to_poly_trait_ref();
let main_trait_ref = main_trait_predicate.to_poly_trait_ref();
let leaf_trait_ref = leaf_trait_predicate.to_poly_trait_ref();
if let Some(guar) = self.emit_specialized_closure_kind_error(
&obligation,
trait_ref,
leaf_trait_ref,
) {
return guar;
}
@ -473,7 +474,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
// FIXME(effects)
let predicate_is_const = false;
if let Err(guar) = trait_predicate.error_reported()
if let Err(guar) = leaf_trait_predicate.error_reported()
{
return guar;
}
@ -507,16 +508,17 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
notes,
parent_label,
append_const_msg,
} = self.on_unimplemented_note(trait_ref, o, &mut long_ty_file);
} = self.on_unimplemented_note(main_trait_ref, o, &mut long_ty_file);
let have_alt_message = message.is_some() || label.is_some();
let is_try_conversion = self.is_try_conversion(span, trait_ref.def_id());
let is_try_conversion = self.is_try_conversion(span, main_trait_ref.def_id());
let is_unsize =
Some(trait_ref.def_id()) == self.tcx.lang_items().unsize_trait();
Some(leaf_trait_ref.def_id()) == self.tcx.lang_items().unsize_trait();
let (message, notes, append_const_msg) = if is_try_conversion {
(
Some(format!(
"`?` couldn't convert the error to `{}`",
trait_ref.skip_binder().self_ty(),
main_trait_ref.skip_binder().self_ty(),
)),
vec![
"the question mark operation (`?`) implicitly performs a \
@ -530,20 +532,20 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
};
let err_msg = self.get_standard_error_message(
&main_trait_predicate,
main_trait_predicate,
message,
predicate_is_const,
append_const_msg,
post_message,
);
let (err_msg, safe_transmute_explanation) = if Some(trait_ref.def_id())
let (err_msg, safe_transmute_explanation) = if Some(main_trait_ref.def_id())
== self.tcx.lang_items().transmute_trait()
{
// Recompute the safe transmute reason and use that for the error reporting
match self.get_safe_transmute_error_and_reason(
obligation.clone(),
trait_ref,
main_trait_ref,
span,
) {
GetSafeTransmuteErrorAndReason::Silent => {
@ -571,7 +573,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
}
let mut suggested = false;
if is_try_conversion {
suggested = self.try_conversion_context(&obligation, trait_ref.skip_binder(), &mut err);
suggested = self.try_conversion_context(&obligation, main_trait_ref.skip_binder(), &mut err);
}
if is_try_conversion && let Some(ret_span) = self.return_type_span(&obligation) {
@ -579,19 +581,19 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
ret_span,
format!(
"expected `{}` because of this",
trait_ref.skip_binder().self_ty()
main_trait_ref.skip_binder().self_ty()
),
);
}
if Some(trait_ref.def_id()) == tcx.lang_items().tuple_trait() {
if Some(leaf_trait_ref.def_id()) == tcx.lang_items().tuple_trait() {
self.add_tuple_trait_message(
obligation.cause.code().peel_derives(),
&mut err,
);
}
if Some(trait_ref.def_id()) == tcx.lang_items().drop_trait()
if Some(leaf_trait_ref.def_id()) == tcx.lang_items().drop_trait()
&& predicate_is_const
{
err.note("`~const Drop` was renamed to `~const Destruct`");
@ -601,24 +603,25 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
let explanation = get_explanation_based_on_obligation(
self.tcx,
&obligation,
trait_ref,
&trait_predicate,
leaf_trait_predicate,
pre_message,
);
self.check_for_binding_assigned_block_without_tail_expression(
&obligation,
&mut err,
trait_predicate,
leaf_trait_predicate,
);
self.suggest_add_result_as_return_type(&obligation,
self.suggest_add_result_as_return_type(
&obligation,
&mut err,
trait_ref);
leaf_trait_predicate,
);
if self.suggest_add_reference_to_arg(
&obligation,
&mut err,
trait_predicate,
leaf_trait_predicate,
have_alt_message,
) {
self.note_obligation_cause(&mut err, &obligation);
@ -630,7 +633,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
// If it has a custom `#[rustc_on_unimplemented]`
// error message, let's display it as the label!
err.span_label(span, s);
if !matches!(trait_ref.skip_binder().self_ty().kind(), ty::Param(_)) {
if !matches!(leaf_trait_ref.skip_binder().self_ty().kind(), ty::Param(_)) {
// When the self type is a type param We don't need to "the trait
// `std::marker::Sized` is not implemented for `T`" as we will point
// at the type param with a label to suggest constraining it.
@ -645,7 +648,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
if let ObligationCauseCode::Coercion { source, target } =
*obligation.cause.code().peel_derives()
{
if Some(trait_ref.def_id()) == self.tcx.lang_items().sized_trait() {
if Some(leaf_trait_ref.def_id()) == self.tcx.lang_items().sized_trait() {
self.suggest_borrowing_for_object_cast(
&mut err,
root_obligation,
@ -657,7 +660,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
let UnsatisfiedConst(unsatisfied_const) = self
.maybe_add_note_for_unsatisfied_const(
&trait_predicate,
leaf_trait_predicate,
&mut err,
span,
);
@ -674,15 +677,15 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
err.span_label(tcx.def_span(body), s);
}
self.suggest_floating_point_literal(&obligation, &mut err, &trait_ref);
self.suggest_dereferencing_index(&obligation, &mut err, trait_predicate);
suggested |= self.suggest_dereferences(&obligation, &mut err, trait_predicate);
suggested |= self.suggest_fn_call(&obligation, &mut err, trait_predicate);
let impl_candidates = self.find_similar_impl_candidates(trait_predicate);
self.suggest_floating_point_literal(&obligation, &mut err, leaf_trait_ref);
self.suggest_dereferencing_index(&obligation, &mut err, leaf_trait_predicate);
suggested |= self.suggest_dereferences(&obligation, &mut err, leaf_trait_predicate);
suggested |= self.suggest_fn_call(&obligation, &mut err, leaf_trait_predicate);
let impl_candidates = self.find_similar_impl_candidates(leaf_trait_predicate);
suggested = if let &[cand] = &impl_candidates[..] {
let cand = cand.trait_ref;
if let (ty::FnPtr(_), ty::FnDef(..)) =
(cand.self_ty().kind(), trait_ref.self_ty().skip_binder().kind())
(cand.self_ty().kind(), main_trait_ref.self_ty().skip_binder().kind())
{
err.span_suggestion(
span.shrink_to_hi(),
@ -702,31 +705,31 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
false
} || suggested;
suggested |=
self.suggest_remove_reference(&obligation, &mut err, trait_predicate);
self.suggest_remove_reference(&obligation, &mut err, leaf_trait_predicate);
suggested |= self.suggest_semicolon_removal(
&obligation,
&mut err,
span,
trait_predicate,
leaf_trait_predicate,
);
self.note_version_mismatch(&mut err, &trait_ref);
self.note_version_mismatch(&mut err, leaf_trait_ref);
self.suggest_remove_await(&obligation, &mut err);
self.suggest_derive(&obligation, &mut err, trait_predicate);
self.suggest_derive(&obligation, &mut err, leaf_trait_predicate);
if Some(trait_ref.def_id()) == tcx.lang_items().try_trait() {
if Some(leaf_trait_ref.def_id()) == tcx.lang_items().try_trait() {
self.suggest_await_before_try(
&mut err,
&obligation,
trait_predicate,
leaf_trait_predicate,
span,
);
}
if self.suggest_add_clone_to_arg(&obligation, &mut err, trait_predicate) {
if self.suggest_add_clone_to_arg(&obligation, &mut err, leaf_trait_predicate) {
return err.emit();
}
if self.suggest_impl_trait(&mut err, &obligation, trait_predicate) {
if self.suggest_impl_trait(&mut err, &obligation, leaf_trait_predicate) {
return err.emit();
}
@ -741,9 +744,9 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
);
}
let is_fn_trait = tcx.is_fn_trait(trait_ref.def_id());
let is_fn_trait = tcx.is_fn_trait(leaf_trait_ref.def_id());
let is_target_feature_fn = if let ty::FnDef(def_id, _) =
*trait_ref.skip_binder().self_ty().kind()
*leaf_trait_ref.skip_binder().self_ty().kind()
{
!self.tcx.codegen_fn_attrs(def_id).target_features.is_empty()
} else {
@ -757,8 +760,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
self.try_to_add_help_message(
&obligation,
trait_ref,
&trait_predicate,
leaf_trait_predicate,
&mut err,
span,
is_fn_trait,
@ -769,17 +771,17 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
// Changing mutability doesn't make a difference to whether we have
// an `Unsize` impl (Fixes ICE in #71036)
if !is_unsize {
self.suggest_change_mut(&obligation, &mut err, trait_predicate);
self.suggest_change_mut(&obligation, &mut err, leaf_trait_predicate);
}
// If this error is due to `!: Trait` not implemented but `(): Trait` is
// implemented, and fallback has occurred, then it could be due to a
// variable that used to fallback to `()` now falling back to `!`. Issue a
// note informing about the change in behaviour.
if trait_predicate.skip_binder().self_ty().is_never()
if leaf_trait_predicate.skip_binder().self_ty().is_never()
&& self.fallback_has_occurred
{
let predicate = trait_predicate.map_bound(|trait_pred| {
let predicate = leaf_trait_predicate.map_bound(|trait_pred| {
trait_pred.with_self_ty(self.tcx, tcx.types.unit)
});
let unit_obligation = obligation.with(tcx, predicate);
@ -794,8 +796,8 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
}
}
self.explain_hrtb_projection(&mut err, trait_predicate, obligation.param_env, &obligation.cause);
self.suggest_desugaring_async_fn_in_trait(&mut err, trait_ref);
self.explain_hrtb_projection(&mut err, leaf_trait_predicate, obligation.param_env, &obligation.cause);
self.suggest_desugaring_async_fn_in_trait(&mut err, main_trait_ref);
// Return early if the trait is Debug or Display and the invocation
// originates within a standard library macro, because the output
@ -813,15 +815,13 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
if in_std_macro
&& matches!(
self.tcx.get_diagnostic_name(trait_ref.def_id()),
self.tcx.get_diagnostic_name(leaf_trait_ref.def_id()),
Some(sym::Debug | sym::Display)
)
{
return err.emit();
}
err
}
@ -2236,11 +2236,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
/// If the `Self` type of the unsatisfied trait `trait_ref` implements a trait
/// with the same path as `trait_ref`, a help message about
/// a probable version mismatch is added to `err`
fn note_version_mismatch(
&self,
err: &mut Diag<'_>,
trait_ref: &ty::PolyTraitRef<'tcx>,
) -> bool {
fn note_version_mismatch(&self, err: &mut Diag<'_>, trait_ref: ty::PolyTraitRef<'tcx>) -> bool {
let get_trait_impls = |trait_def_id| {
let mut trait_impls = vec![];
self.tcx.for_each_relevant_impl(
@ -2705,6 +2701,22 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
),
);
}
ty::PredicateKind::NormalizesTo(ty::NormalizesTo { alias, term })
if term.is_infer() =>
{
if let Some(e) = self.tainted_by_errors() {
return e;
}
struct_span_code_err!(
self.dcx(),
span,
E0284,
"type annotations needed: cannot normalize `{alias}`",
)
.with_span_label(span, format!("cannot normalize `{alias}`"))
}
_ => {
if let Some(e) = self.tainted_by_errors() {
return e;
@ -3044,7 +3056,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
fn get_standard_error_message(
&self,
trait_predicate: &ty::PolyTraitPredicate<'tcx>,
trait_predicate: ty::PolyTraitPredicate<'tcx>,
message: Option<String>,
predicate_is_const: bool,
append_const_msg: Option<AppendConstMessage>,
@ -3215,8 +3227,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
fn try_to_add_help_message(
&self,
obligation: &PredicateObligation<'tcx>,
trait_ref: ty::PolyTraitRef<'tcx>,
trait_predicate: &ty::PolyTraitPredicate<'tcx>,
trait_predicate: ty::PolyTraitPredicate<'tcx>,
err: &mut Diag<'_>,
span: Span,
is_fn_trait: bool,
@ -3233,16 +3244,22 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
};
// Try to report a help message
let trait_def_id = trait_predicate.def_id();
if is_fn_trait
&& let Ok((implemented_kind, params)) = self.type_implements_fn_trait(
obligation.param_env,
trait_ref.self_ty(),
trait_predicate.self_ty(),
trait_predicate.skip_binder().polarity,
)
{
self.add_help_message_for_fn_trait(trait_ref, err, implemented_kind, params);
} else if !trait_ref.has_non_region_infer()
&& self.predicate_can_apply(obligation.param_env, *trait_predicate)
self.add_help_message_for_fn_trait(
trait_predicate.to_poly_trait_ref(),
err,
implemented_kind,
params,
);
} else if !trait_predicate.has_non_region_infer()
&& self.predicate_can_apply(obligation.param_env, trait_predicate)
{
// If a where-clause may be useful, remind the
// user that they can add it.
@ -3253,25 +3270,25 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
// which is somewhat confusing.
self.suggest_restricting_param_bound(
err,
*trait_predicate,
trait_predicate,
None,
obligation.cause.body_id,
);
} else if trait_ref.def_id().is_local()
&& self.tcx.trait_impls_of(trait_ref.def_id()).is_empty()
&& !self.tcx.trait_is_auto(trait_ref.def_id())
&& !self.tcx.trait_is_alias(trait_ref.def_id())
} else if trait_def_id.is_local()
&& self.tcx.trait_impls_of(trait_def_id).is_empty()
&& !self.tcx.trait_is_auto(trait_def_id)
&& !self.tcx.trait_is_alias(trait_def_id)
{
err.span_help(
self.tcx.def_span(trait_ref.def_id()),
self.tcx.def_span(trait_def_id),
crate::fluent_generated::trait_selection_trait_has_no_impls,
);
} else if !suggested && !unsatisfied_const {
// Can't show anything else useful, try to find similar impls.
let impl_candidates = self.find_similar_impl_candidates(*trait_predicate);
let impl_candidates = self.find_similar_impl_candidates(trait_predicate);
if !self.report_similar_impl_candidates(
&impl_candidates,
trait_ref,
trait_predicate.to_poly_trait_ref(),
body_def_id,
err,
true,
@ -3279,7 +3296,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
) {
self.report_similar_impl_candidates_for_root_obligation(
obligation,
*trait_predicate,
trait_predicate,
body_def_id,
err,
);
@ -3288,7 +3305,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
self.suggest_convert_to_slice(
err,
obligation,
trait_ref,
trait_predicate.to_poly_trait_ref(),
impl_candidates.as_slice(),
span,
);
@ -3353,7 +3370,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
fn maybe_add_note_for_unsatisfied_const(
&self,
_trait_predicate: &ty::PolyTraitPredicate<'tcx>,
_trait_predicate: ty::PolyTraitPredicate<'tcx>,
_err: &mut Diag<'_>,
_span: Span,
) -> UnsatisfiedConst {

View File

@ -194,7 +194,7 @@ fn predicates_reference_self(
predicates
.predicates
.iter()
.map(|&(predicate, sp)| (predicate.instantiate_supertrait(tcx, &trait_ref), sp))
.map(|&(predicate, sp)| (predicate.instantiate_supertrait(tcx, trait_ref), sp))
.filter_map(|predicate| predicate_references_self(tcx, predicate))
.collect()
}

View File

@ -1,10 +1,10 @@
use rustc_infer::infer::relate::{
self, structurally_relate_tys, Relate, RelateResult, TypeRelation,
};
use rustc_middle::ty::error::{ExpectedFound, TypeError};
use rustc_middle::ty::{self, InferConst, Ty, TyCtxt};
use tracing::{debug, instrument};
use super::{structurally_relate_tys, Relate, RelateResult, TypeRelation};
use crate::infer::relate;
/// A type "A" *matches* "B" if the fresh types in B could be
/// instantiated with values so as to make it equal to A. Matching is
/// intended to be used only on freshened types, and it basically

View File

@ -32,7 +32,6 @@ use rustc_data_structures::stack::ensure_sufficient_stack;
use rustc_errors::{Diag, EmissionGuarantee};
use rustc_hir as hir;
use rustc_hir::def_id::DefId;
use rustc_infer::infer::relate::MatchAgainstFreshVars;
use rustc_infer::infer::relate::TypeRelation;
use rustc_infer::infer::BoundRegionConversionTime;
use rustc_infer::infer::BoundRegionConversionTime::HigherRankedType;
@ -60,6 +59,7 @@ use std::ops::ControlFlow;
pub use rustc_middle::traits::select::*;
use rustc_middle::ty::print::with_no_trimmed_paths;
mod _match;
mod candidate_assembly;
mod confirmation;
@ -1866,7 +1866,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
// the param_env so that it can be given the lowest priority. See
// #50825 for the motivation for this.
let is_global =
|cand: &ty::PolyTraitPredicate<'tcx>| cand.is_global() && !cand.has_bound_vars();
|cand: ty::PolyTraitPredicate<'tcx>| cand.is_global() && !cand.has_bound_vars();
// (*) Prefer `BuiltinCandidate { has_nested: false }`, `PointeeCandidate`,
// `DiscriminantKindCandidate`, `ConstDestructCandidate`
@ -1909,7 +1909,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
}
(
ParamCandidate(ref other_cand),
ParamCandidate(other_cand),
ImplCandidate(..)
| AutoImplCandidate
| ClosureCandidate { .. }
@ -1934,12 +1934,12 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
//
// Global bounds from the where clause should be ignored
// here (see issue #50825).
DropVictim::drop_if(!is_global(other_cand))
DropVictim::drop_if(!is_global(*other_cand))
}
(ObjectCandidate(_) | ProjectionCandidate(_), ParamCandidate(ref victim_cand)) => {
(ObjectCandidate(_) | ProjectionCandidate(_), ParamCandidate(victim_cand)) => {
// Prefer these to a global where-clause bound
// (see issue #50825).
if is_global(victim_cand) { DropVictim::Yes } else { DropVictim::No }
if is_global(*victim_cand) { DropVictim::Yes } else { DropVictim::No }
}
(
ImplCandidate(_)
@ -1957,12 +1957,12 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
| TraitUpcastingUnsizeCandidate(_)
| BuiltinCandidate { has_nested: true }
| TraitAliasCandidate,
ParamCandidate(ref victim_cand),
ParamCandidate(victim_cand),
) => {
// Prefer these to a global where-clause bound
// (see issue #50825).
DropVictim::drop_if(
is_global(victim_cand) && other.evaluation.must_apply_modulo_regions(),
is_global(*victim_cand) && other.evaluation.must_apply_modulo_regions(),
)
}
@ -2719,7 +2719,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
previous: ty::PolyTraitPredicate<'tcx>,
current: ty::PolyTraitPredicate<'tcx>,
) -> bool {
let mut matcher = MatchAgainstFreshVars::new(self.tcx());
let mut matcher = _match::MatchAgainstFreshVars::new(self.tcx());
matcher.relate(previous, current).is_ok()
}

View File

@ -132,7 +132,7 @@ impl<'tcx> TraitAliasExpander<'tcx> {
debug!(?predicates);
let items = predicates.predicates.iter().rev().filter_map(|(pred, span)| {
pred.instantiate_supertrait(tcx, &trait_ref)
pred.instantiate_supertrait(tcx, trait_ref)
.as_trait_clause()
.map(|trait_ref| item.clone_and_push(trait_ref.map_bound(|t| t.trait_ref), *span))
});

View File

@ -125,7 +125,7 @@ fn prepare_vtable_segments_inner<'tcx, T>(
.predicates
.into_iter()
.filter_map(move |(pred, _)| {
pred.instantiate_supertrait(tcx, &inner_most_trait_ref).as_trait_clause()
pred.instantiate_supertrait(tcx, inner_most_trait_ref).as_trait_clause()
});
// Find an unvisited supertrait

View File

@ -331,30 +331,63 @@ pub(crate) mod rustc {
assert!(def.is_enum());
let layout = ty_and_layout.layout;
if let Variants::Multiple { tag_field, .. } = layout.variants() {
// For enums (but not coroutines), the tag field is
// currently always the first field of the layout.
assert_eq!(*tag_field, 0);
}
// Computes the variant of a given index.
let layout_of_variant = |index| {
let tag = cx.tcx.tag_for_variant((ty_and_layout.ty, index));
let variant_def = Def::Variant(def.variant(index));
let variant_ty_and_layout = ty_and_layout.for_variant(&cx, index);
Self::from_variant(variant_def, tag, variant_ty_and_layout, layout.size, cx)
};
let variants = def.discriminants(cx.tcx()).try_fold(
Self::uninhabited(),
|variants, (idx, ref discriminant)| {
let tag = cx.tcx.tag_for_variant((ty_and_layout.ty, idx));
let variant_def = Def::Variant(def.variant(idx));
let variant_ty_and_layout = ty_and_layout.for_variant(&cx, idx);
let variant = Self::from_variant(
variant_def,
tag,
variant_ty_and_layout,
layout.size,
cx,
// We consider three kinds of enums, each demanding a different
// treatment of their layout computation:
// 1. enums that are uninhabited
// 2. enums for which all but one variant is uninhabited
// 3. enums with multiple inhabited variants
match layout.variants() {
_ if layout.abi.is_uninhabited() => {
// Uninhabited enums are usually (always?) zero-sized. In
// the (unlikely?) event that an uninhabited enum is
// non-zero-sized, this assert will trigger an ICE, and this
// code should be modified such that a `layout.size` amount
// of uninhabited bytes is returned instead.
//
// Uninhabited enums are currently implemented such that
// their layout is described with `Variants::Single`, even
// though they don't necessarily have a 'single' variant to
// defer to. That said, we don't bother specifically
// matching on `Variants::Single` in this arm because the
// behavioral principles here remain true even if, for
// whatever reason, the compiler describes an uninhabited
// enum with `Variants::Multiple`.
assert_eq!(layout.size, Size::ZERO);
Ok(Self::uninhabited())
}
Variants::Single { index } => {
// `Variants::Single` on non-uninhabited enums denotes that
// the enum delegates its layout to the variant at `index`.
layout_of_variant(*index)
}
Variants::Multiple { tag_field, .. } => {
// `Variants::Multiple` denotes an enum with multiple
// inhabited variants. The layout of such an enum is the
// disjunction of the layouts of its tagged variants.
// For enums (but not coroutines), the tag field is
// currently always the first field of the layout.
assert_eq!(*tag_field, 0);
let variants = def.discriminants(cx.tcx()).try_fold(
Self::uninhabited(),
|variants, (idx, ref discriminant)| {
let variant = layout_of_variant(idx)?;
Result::<Self, Err>::Ok(variants.or(variant))
},
)?;
Result::<Self, Err>::Ok(variants.or(variant))
},
)?;
return Ok(Self::def(Def::Adt(def)).then(variants));
return Ok(Self::def(Def::Adt(def)).then(variants));
}
}
}
/// Constructs a `Tree` from a 'variant-like' layout.

View File

@ -122,7 +122,7 @@ impl TyConst {
}
/// Creates an interned usize constant.
fn try_from_target_usize(val: u64) -> Result<Self, Error> {
pub fn try_from_target_usize(val: u64) -> Result<Self, Error> {
with(|cx| cx.try_new_ty_const_uint(val.into(), UintTy::Usize))
}

View File

@ -654,6 +654,32 @@ impl<T> Option<T> {
!self.is_some()
}
/// Returns `true` if the option is a [`None`] or the value inside of it matches a predicate.
///
/// # Examples
///
/// ```
/// #![feature(is_none_or)]
///
/// let x: Option<u32> = Some(2);
/// assert_eq!(x.is_none_or(|x| x > 1), true);
///
/// let x: Option<u32> = Some(0);
/// assert_eq!(x.is_none_or(|x| x > 1), false);
///
/// let x: Option<u32> = None;
/// assert_eq!(x.is_none_or(|x| x > 1), true);
/// ```
#[must_use]
#[inline]
#[unstable(feature = "is_none_or", issue = "none")]
pub fn is_none_or(self, f: impl FnOnce(T) -> bool) -> bool {
match self {
None => true,
Some(x) => f(x),
}
}
/////////////////////////////////////////////////////////////////////////
// Adapter for working with references
/////////////////////////////////////////////////////////////////////////

View File

@ -11,8 +11,8 @@ development process.
In order to accomplish that goal, `rustc` accepts the `--check-cfg` flag, which specifies
whether to check conditions and how to check them.
> **Note:** No implicit expectation is added when using `--cfg`. Users are expected to
pass all expected names and values using the _check cfg specification_.
> **Note:** For interacting with this through Cargo,
see [Cargo Specifics](check-cfg/cargo-specifics.md) page.
[^reachable]: `rustc` promises to at least check reachable `#[cfg]`, and while non-reachable
`#[cfg]` are not currently checked, they may well be checked in the future without it being a
@ -23,6 +23,9 @@ breaking change.
To specify expected names and values, the _check cfg specification_ provides the `cfg(...)`
option which enables specifying for an expected config name and it's expected values.
> **Note:** No implicit expectation is added when using `--cfg`. Users are expected to
pass all expected names and values using the _check cfg specification_.
It has this basic form:
```bash

View File

@ -13,6 +13,7 @@
#![feature(lint_reasons)]
#![feature(trait_upcasting)]
#![feature(strict_overflow_ops)]
#![feature(is_none_or)]
// Configure clippy and other lints
#![allow(
clippy::collapsible_else_if,

View File

@ -396,12 +396,12 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
// If the newly promised alignment is bigger than the native alignment of this
// allocation, and bigger than the previously promised alignment, then set it.
if align > alloc_align
&& !this
&& this
.machine
.symbolic_alignment
.get_mut()
.get(&alloc_id)
.is_some_and(|&(_, old_align)| align <= old_align)
.is_none_or(|&(_, old_align)| align > old_align)
{
this.machine.symbolic_alignment.get_mut().insert(alloc_id, (offset, align));
}

View File

@ -95,6 +95,34 @@ pub fn source_root() -> PathBuf {
env_var("SOURCE_ROOT").into()
}
/// Creates a new symlink to a path on the filesystem, adjusting for Windows or Unix.
#[cfg(target_family = "windows")]
pub fn create_symlink<P: AsRef<Path>, Q: AsRef<Path>>(original: P, link: Q) {
if link.as_ref().exists() {
std::fs::remove_dir(link.as_ref()).unwrap();
}
use std::os::windows::fs;
fs::symlink_file(original.as_ref(), link.as_ref()).expect(&format!(
"failed to create symlink {:?} for {:?}",
link.as_ref().display(),
original.as_ref().display(),
));
}
/// Creates a new symlink to a path on the filesystem, adjusting for Windows or Unix.
#[cfg(target_family = "unix")]
pub fn create_symlink<P: AsRef<Path>, Q: AsRef<Path>>(original: P, link: Q) {
if link.as_ref().exists() {
std::fs::remove_dir(link.as_ref()).unwrap();
}
use std::os::unix::fs;
fs::symlink(original.as_ref(), link.as_ref()).expect(&format!(
"failed to create symlink {:?} for {:?}",
link.as_ref().display(),
original.as_ref().display(),
));
}
/// Construct the static library name based on the platform.
pub fn static_lib_name(name: &str) -> String {
// See tools.mk (irrelevant lines omitted):

View File

@ -1387,6 +1387,7 @@ fn generic_args_sans_defaults<'ga>(
}
// otherwise, if the arg is equal to the param default, hide it (unless the
// default is an error which can happen for the trait Self type)
#[allow(unstable_name_collisions)]
default_parameters.get(i).is_none_or(|default_parameter| {
// !is_err(default_parameter.skip_binders())
// &&

View File

@ -226,9 +226,6 @@ run-make/std-core-cycle/Makefile
run-make/symbol-mangling-hashed/Makefile
run-make/symbol-visibility/Makefile
run-make/symbols-include-type-name/Makefile
run-make/symlinked-extern/Makefile
run-make/symlinked-libraries/Makefile
run-make/symlinked-rlib/Makefile
run-make/sysroot-crates-are-unstable/Makefile
run-make/target-cpu-native/Makefile
run-make/target-specs/Makefile

View File

@ -1,34 +0,0 @@
//@ known-bug: rust-lang/rust#125811
mod assert {
use std::mem::{Assume, BikeshedIntrinsicFrom};
pub fn is_transmutable<Src, Dst>()
where
Dst: BikeshedIntrinsicFrom<Src>,
{
}
}
#[repr(C)]
struct Zst;
enum V0 {
B(!),
}
enum V2 {
V = 2,
}
enum Lopsided {
Smol(Zst),
Lorg(V0),
}
#[repr(C)]
#[repr(C)]
struct Dst(Lopsided, V2);
fn should_pad_variants() {
assert::is_transmutable::<Src, Dst>();
}

View File

@ -1,12 +0,0 @@
# ignore-cross-compile
include ../tools.mk
# ignore-windows
# `ln` is actually `cp` on msys.
all:
$(RUSTC) foo.rs
mkdir -p $(TMPDIR)/other
ln -nsf $(TMPDIR)/libfoo.rlib $(TMPDIR)/other
$(RUSTC) bar.rs -L $(TMPDIR)
$(RUSTC) baz.rs --extern foo=$(TMPDIR)/other/libfoo.rlib -L $(TMPDIR)

View File

@ -0,0 +1,21 @@
// Crates that are resolved normally have their path canonicalized and all
// symlinks resolved. This did not happen for paths specified
// using the --extern option to rustc, which could lead to rustc thinking
// that it encountered two different versions of a crate, when it's
// actually the same version found through different paths.
// See https://github.com/rust-lang/rust/pull/16505
// This test checks that --extern and symlinks together
// can result in successful compilation.
//@ ignore-cross-compile
use run_make_support::{create_symlink, cwd, fs_wrapper, rustc};
fn main() {
rustc().input("foo.rs").run();
fs_wrapper::create_dir_all("other");
create_symlink("libfoo.rlib", "other");
rustc().input("bar.rs").library_search_path(cwd()).run();
rustc().input("baz.rs").extern_("foo", "other").library_search_path(cwd()).run();
}

View File

@ -1,11 +0,0 @@
# ignore-cross-compile
include ../tools.mk
# ignore-windows
# `ln` is actually `cp` on msys.
all:
$(RUSTC) foo.rs -C prefer-dynamic
mkdir -p $(TMPDIR)/other
ln -nsf $(TMPDIR)/$(call DYLIB_GLOB,foo) $(TMPDIR)/other
$(RUSTC) bar.rs -L $(TMPDIR)/other

View File

@ -0,0 +1,16 @@
// When a directory and a symlink simultaneously exist with the same name,
// setting that name as the library search path should not cause rustc
// to avoid looking in the symlink and cause an error. This test creates
// a directory and a symlink named "other", and places the library in the symlink.
// If it succeeds, the library was successfully found.
// See https://github.com/rust-lang/rust/issues/12459
//@ ignore-cross-compile
use run_make_support::{create_symlink, dynamic_lib_name, fs_wrapper, rustc};
fn main() {
rustc().input("foo.rs").arg("-Cprefer-dynamic").run();
fs_wrapper::create_dir_all("other");
create_symlink(dynamic_lib_name("foo"), "other");
rustc().input("bar.rs").library_search_path("other").run();
}

View File

@ -1,10 +0,0 @@
# ignore-cross-compile
include ../tools.mk
# ignore-windows
# `ln` is actually `cp` on msys.
all:
$(RUSTC) foo.rs --crate-type=rlib -o $(TMPDIR)/foo.xxx
ln -nsf $(TMPDIR)/foo.xxx $(TMPDIR)/libfoo.rlib
$(RUSTC) bar.rs -L $(TMPDIR)

View File

@ -0,0 +1,16 @@
// Rustc did not recognize libraries which were symlinked
// to files having extension other than .rlib. This was fixed
// in #32828. This test creates a symlink to "foo.xxx", which has
// an unusual file extension, and checks that rustc can successfully
// use it as an rlib library.
// See https://github.com/rust-lang/rust/pull/32828
//@ ignore-cross-compile
use run_make_support::{create_symlink, cwd, rustc};
fn main() {
rustc().input("foo.rs").crate_type("rlib").output("foo.xxx").run();
create_symlink("foo.xxx", "libfoo.rlib");
rustc().input("bar.rs").library_search_path(cwd()).run();
}

View File

@ -2,7 +2,7 @@ error[E0277]: the trait bound `&'static u32: Defaulted` is not satisfied
--> $DIR/typeck-default-trait-impl-precedence.rs:19:20
|
LL | is_defaulted::<&'static u32>();
| ^^^^^^^^^^^^ the trait `Signed` is not implemented for `&'static u32`, which is required by `&'static u32: Defaulted`
| ^^^^^^^^^^^^ the trait `Signed` is not implemented for `u32`, which is required by `&'static u32: Defaulted`
|
note: required for `&'static u32` to implement `Defaulted`
--> $DIR/typeck-default-trait-impl-precedence.rs:10:19

View File

@ -1,8 +1,8 @@
error[E0284]: type annotations needed: cannot satisfy `<dyn Object<U, Output = T> as Object<U>>::Output == T`
error[E0284]: type annotations needed: cannot normalize `<dyn Object<U, Output = T> as Object<U>>::Output`
--> $DIR/indirect-impl-for-trait-obj-coherence.rs:25:41
|
LL | foo::<dyn Object<U, Output = T>, U>(x)
| ^ cannot satisfy `<dyn Object<U, Output = T> as Object<U>>::Output == T`
| ^ cannot normalize `<dyn Object<U, Output = T> as Object<U>>::Output`
error: aborting due to 1 previous error

View File

@ -23,7 +23,7 @@ fn foo<T: ?Sized, U>(x: <T as Object<U>>::Output) -> U {
#[allow(dead_code)]
fn transmute<T, U>(x: T) -> U {
foo::<dyn Object<U, Output = T>, U>(x)
//[next]~^ ERROR type annotations needed: cannot satisfy `<dyn Object<U, Output = T> as Object<U>>::Output == T`
//[next]~^ ERROR type annotations needed: cannot normalize `<dyn Object<U, Output = T> as Object<U>>::Output`
}
fn main() {}

View File

@ -16,11 +16,11 @@ LL | | for<'a> *const T: ToUnit<'a>,
|
= note: this behavior recently changed as a result of a bug fix; see rust-lang/rust#56105 for details
error[E0284]: type annotations needed: cannot satisfy `<for<'a> fn(&'a (), ()) as Overlap<for<'a> fn(&'a (), ())>>::Assoc == usize`
error[E0284]: type annotations needed: cannot normalize `<for<'a> fn(&'a (), ()) as Overlap<for<'a> fn(&'a (), ())>>::Assoc`
--> $DIR/associated-type.rs:44:59
|
LL | foo::<for<'a> fn(&'a (), ()), for<'a> fn(&'a (), ())>(3usize);
| ^^^^^^ cannot satisfy `<for<'a> fn(&'a (), ()) as Overlap<for<'a> fn(&'a (), ())>>::Assoc == usize`
| ^^^^^^ cannot normalize `<for<'a> fn(&'a (), ()) as Overlap<for<'a> fn(&'a (), ())>>::Assoc`
error: aborting due to 2 previous errors

View File

@ -42,5 +42,5 @@ fn foo<T: Overlap<U>, U>(x: T::Assoc) -> T::Assoc {
fn main() {
foo::<for<'a> fn(&'a (), ()), for<'a> fn(&'a (), ())>(3usize);
//[next]~^ ERROR: cannot satisfy
//[next]~^ ERROR: cannot normalize
}

View File

@ -25,7 +25,7 @@ LL | SelectInt.check("bar");
= help: the trait `AsExpression<Text>` is implemented for `&str`
= help: for that trait implementation, expected `Text`, found `Integer`
error[E0271]: type mismatch resolving `<&str as AsExpression<<SelectInt as Expression>::SqlType>>::Expression == _`
error[E0271]: type mismatch resolving `<SelectInt as Expression>::SqlType == Text`
--> $DIR/as_expression.rs:57:5
|
LL | SelectInt.check("bar");

View File

@ -2,7 +2,7 @@ error[E0277]: the trait bound `i32: Baz<Self>` is not satisfied
--> $DIR/assume-gat-normalization-for-nested-goals.rs:9:30
|
LL | type Bar<T>: Baz<Self> = i32;
| ^^^ the trait `Eq<i32>` is not implemented for `i32`, which is required by `i32: Baz<Self>`
| ^^^ the trait `Eq<i32>` is not implemented for `<Self as Foo>::Bar<()>`, which is required by `i32: Baz<Self>`
|
note: required for `i32` to implement `Baz<Self>`
--> $DIR/assume-gat-normalization-for-nested-goals.rs:16:23

View File

@ -1,8 +1,8 @@
error[E0284]: type annotations needed: cannot satisfy `for<'a> <_ as Trait<'a>>::Assoc <: <T as Trait<'_>>::Assoc`
error[E0284]: type annotations needed: cannot satisfy `for<'a> <_ as Trait<'a>>::Assoc normalizes-to <T as Trait<'_>>::Assoc`
--> $DIR/rigid-equate-projections-in-higher-ranked-fn-signature.rs:27:50
|
LL | let _: for<'a> fn(<_ as Trait<'a>>::Assoc) = foo::<T>();
| ^^^^^^^^^^ cannot satisfy `for<'a> <_ as Trait<'a>>::Assoc <: <T as Trait<'_>>::Assoc`
| ^^^^^^^^^^ cannot satisfy `for<'a> <_ as Trait<'a>>::Assoc normalizes-to <T as Trait<'_>>::Assoc`
error: aborting due to 1 previous error

View File

@ -0,0 +1,28 @@
#![feature(impl_trait_in_assoc_type)]
trait Foo: Sized {
type Bar;
type Gat<T: Foo>;
fn foo(self) -> (<Self as Foo>::Gat<u32>, <Self as Foo>::Gat<Self>);
}
impl Foo for u32 {
type Bar = ();
type Gat<T: Foo> = ();
fn foo(self) -> (<Self as Foo>::Gat<u32>, <Self as Foo>::Gat<Self>) {
((), ())
}
}
impl Foo for () {
type Bar = impl Sized;
type Gat<T: Foo> = <T as Foo>::Bar;
// Because we encounter `Gat<u32>` first, we never walk into another `Gat`
// again, thus missing the opaque type that we could be defining.
fn foo(self) -> (<Self as Foo>::Gat<u32>, <Self as Foo>::Gat<Self>) {
((), ())
//~^ ERROR: mismatched types
}
}
fn main() {}

View File

@ -0,0 +1,20 @@
error[E0308]: mismatched types
--> $DIR/associated-type-undefine.rs:23:14
|
LL | type Bar = impl Sized;
| ---------- the expected opaque type
...
LL | ((), ())
| ^^ expected opaque type, found `()`
|
= 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/associated-type-undefine.rs:22:8
|
LL | fn foo(self) -> (<Self as Foo>::Gat<u32>, <Self as Foo>::Gat<Self>) {
| ^^^
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0308`.

View File

@ -46,7 +46,7 @@ error[E0277]: the trait bound `impl Into<u32>: Into<impl Debug>` is not satisfie
--> $DIR/nested_impl_trait.rs:6:46
|
LL | fn bad_in_ret_position(x: impl Into<u32>) -> impl Into<impl Debug> { x }
| ^^^^^^^^^^^^^^^^^^^^^ the trait `From<impl Into<u32>>` is not implemented for `impl Into<u32>`, which is required by `impl Into<u32>: Into<impl Debug>`
| ^^^^^^^^^^^^^^^^^^^^^ the trait `From<impl Into<u32>>` is not implemented for `impl Debug`, which is required by `impl Into<u32>: Into<impl Debug>`
|
= help: the trait `Into<U>` is implemented for `T`
= note: required for `impl Into<u32>` to implement `Into<impl Debug>`
@ -55,7 +55,7 @@ error[E0277]: the trait bound `impl Into<u32>: Into<impl Debug>` is not satisfie
--> $DIR/nested_impl_trait.rs:19:34
|
LL | fn bad(x: impl Into<u32>) -> impl Into<impl Debug> { x }
| ^^^^^^^^^^^^^^^^^^^^^ the trait `From<impl Into<u32>>` is not implemented for `impl Into<u32>`, which is required by `impl Into<u32>: Into<impl Debug>`
| ^^^^^^^^^^^^^^^^^^^^^ the trait `From<impl Into<u32>>` is not implemented for `impl Debug`, which is required by `impl Into<u32>: Into<impl Debug>`
|
= help: the trait `Into<U>` is implemented for `T`
= note: required for `impl Into<u32>` to implement `Into<impl Debug>`

View File

@ -4,7 +4,7 @@ error[E0277]: `&'static (dyn Dummy + 'static)` cannot be sent between threads sa
LL | assert_send::<&'static (dyn Dummy + 'static)>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `&'static (dyn Dummy + 'static)` cannot be sent between threads safely
|
= help: the trait `Sync` is not implemented for `&'static (dyn Dummy + 'static)`, which is required by `&'static (dyn Dummy + 'static): Send`
= help: the trait `Sync` is not implemented for `(dyn Dummy + 'static)`, which is required by `&'static (dyn Dummy + 'static): Send`
= note: required for `&'static (dyn Dummy + 'static)` to implement `Send`
note: required by a bound in `assert_send`
--> $DIR/kindck-send-object.rs:5:18

View File

@ -4,7 +4,7 @@ error[E0277]: `&'a (dyn Dummy + 'a)` cannot be sent between threads safely
LL | assert_send::<&'a dyn Dummy>();
| ^^^^^^^^^^^^^ `&'a (dyn Dummy + 'a)` cannot be sent between threads safely
|
= help: the trait `Sync` is not implemented for `&'a (dyn Dummy + 'a)`, which is required by `&'a (dyn Dummy + 'a): Send`
= help: the trait `Sync` is not implemented for `(dyn Dummy + 'a)`, which is required by `&'a (dyn Dummy + 'a): Send`
= note: required for `&'a (dyn Dummy + 'a)` to implement `Send`
note: required by a bound in `assert_send`
--> $DIR/kindck-send-object1.rs:5:18

View File

@ -4,7 +4,7 @@ error[E0277]: `&'static (dyn Dummy + 'static)` cannot be sent between threads sa
LL | assert_send::<&'static dyn Dummy>();
| ^^^^^^^^^^^^^^^^^^ `&'static (dyn Dummy + 'static)` cannot be sent between threads safely
|
= help: the trait `Sync` is not implemented for `&'static (dyn Dummy + 'static)`, which is required by `&'static (dyn Dummy + 'static): Send`
= help: the trait `Sync` is not implemented for `(dyn Dummy + 'static)`, which is required by `&'static (dyn Dummy + 'static): Send`
= note: required for `&'static (dyn Dummy + 'static)` to implement `Send`
note: required by a bound in `assert_send`
--> $DIR/kindck-send-object2.rs:3:18

View File

@ -4,7 +4,7 @@ error[E0277]: `&mut &mut &mut &mut Vec<i32>` is not an iterator
LL | for _ in &mut &mut v {}
| ^^^^^^^^^^^ `&mut &mut &mut &mut Vec<i32>` is not an iterator
|
= help: the trait `Iterator` is not implemented for `&mut &mut &mut &mut Vec<i32>`, which is required by `&mut &mut &mut &mut Vec<i32>: IntoIterator`
= help: the trait `Iterator` is not implemented for `Vec<i32>`, which is required by `&mut &mut &mut &mut Vec<i32>: IntoIterator`
= note: required for `&mut Vec<i32>` to implement `Iterator`
= note: 3 redundant requirements hidden
= note: required for `&mut &mut &mut &mut Vec<i32>` to implement `Iterator`
@ -21,7 +21,7 @@ error[E0277]: `&mut &mut &mut [u8; 1]` is not an iterator
LL | for _ in &mut v {}
| ^^^^^^ `&mut &mut &mut [u8; 1]` is not an iterator
|
= help: the trait `Iterator` is not implemented for `&mut &mut &mut [u8; 1]`, which is required by `&mut &mut &mut [u8; 1]: IntoIterator`
= help: the trait `Iterator` is not implemented for `[u8; 1]`, which is required by `&mut &mut &mut [u8; 1]: IntoIterator`
= note: required for `&mut [u8; 1]` to implement `Iterator`
= note: 2 redundant requirements hidden
= note: required for `&mut &mut &mut [u8; 1]` to implement `Iterator`

View File

@ -18,3 +18,4 @@ fn weird1() -> impl !Sized + Sized {}
//~^ ERROR type mismatch resolving `impl !Sized + Sized == ()`
fn weird2() -> impl !Sized {}
//~^ ERROR type mismatch resolving `impl !Sized == ()`
//~| ERROR the size for values of type `impl !Sized` cannot be known at compilation time

View File

@ -16,6 +16,15 @@ error[E0271]: type mismatch resolving `impl !Sized == ()`
LL | fn weird2() -> impl !Sized {}
| ^^^^^^^^^^^ types differ
error[E0277]: the size for values of type `impl !Sized` cannot be known at compilation time
--> $DIR/opaque-type-unsatisfied-bound.rs:19:16
|
LL | fn weird2() -> impl !Sized {}
| ^^^^^^^^^^^ doesn't have a size known at compile-time
|
= help: the trait `Sized` is not implemented for `impl !Sized`
= note: the return type of a function must have a statically known size
error[E0277]: the trait bound `impl !Trait: Trait` is not satisfied
--> $DIR/opaque-type-unsatisfied-bound.rs:12:13
|
@ -30,7 +39,7 @@ note: required by a bound in `consume`
LL | fn consume(_: impl Trait) {}
| ^^^^^ required by this bound in `consume`
error: aborting due to 4 previous errors
error: aborting due to 5 previous errors
Some errors have detailed explanations: E0271, E0277.
For more information about an error, try `rustc --explain E0271`.

View File

@ -4,7 +4,7 @@ error: future cannot be sent between threads safely
LL | is_send(foo());
| ^^^^^ future returned by `foo` is not `Send`
|
= help: the trait `Sync` is not implemented for `impl Future<Output = ()>`, which is required by `impl Future<Output = ()>: Send`
= help: the trait `Sync` is not implemented for `NotSync`, which is required by `impl Future<Output = ()>: Send`
note: future is not `Send` as this value is used across an await
--> $DIR/auto-with-drop_tracking_mir.rs:16:11
|

View File

@ -1,8 +1,8 @@
error[E0284]: type annotations needed: cannot satisfy `{ || {} } == _`
error[E0284]: type annotations needed: cannot normalize `X::{constant#0}`
--> $DIR/const-region-infer-to-static-in-binder.rs:4:10
|
LL | struct X<const FN: fn() = { || {} }>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot satisfy `{ || {} } == _`
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot normalize `X::{constant#0}`
error: using function pointers as const generic parameters is forbidden
--> $DIR/const-region-infer-to-static-in-binder.rs:4:20

View File

@ -4,6 +4,11 @@ error[E0277]: the trait bound `(): Foo` is not satisfied
LL | needs_foo::<()>();
| ^^ the trait `Bar` is not implemented for `()`, which is required by `(): Foo`
|
help: this trait has no implementations, consider adding one
--> $DIR/point-at-failing-nested.rs:4:1
|
LL | trait Bar {}
| ^^^^^^^^^
note: required for `()` to implement `Foo`
--> $DIR/point-at-failing-nested.rs:9:12
|

View File

@ -0,0 +1,17 @@
//@ compile-flags: -Znext-solver
trait Trait {
type Assoc;
}
fn test_poly<T>() {
let x: <T as Trait>::Assoc = ();
//~^ ERROR the trait bound `T: Trait` is not satisfied
}
fn test() {
let x: <i32 as Trait>::Assoc = ();
//~^ ERROR the trait bound `i32: Trait` is not satisfied
}
fn main() {}

View File

@ -0,0 +1,26 @@
error[E0277]: the trait bound `T: Trait` is not satisfied
--> $DIR/projection-trait-ref.rs:8:12
|
LL | let x: <T as Trait>::Assoc = ();
| ^^^^^^^^^^^^^^^^^^^ the trait `Trait` is not implemented for `T`
|
help: consider restricting type parameter `T`
|
LL | fn test_poly<T: Trait>() {
| +++++++
error[E0277]: the trait bound `i32: Trait` is not satisfied
--> $DIR/projection-trait-ref.rs:13:12
|
LL | let x: <i32 as Trait>::Assoc = ();
| ^^^^^^^^^^^^^^^^^^^^^ the trait `Trait` is not implemented for `i32`
|
help: this trait has no implementations, consider adding one
--> $DIR/projection-trait-ref.rs:3:1
|
LL | trait Trait {
| ^^^^^^^^^^^
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0277`.

View File

@ -6,6 +6,11 @@ LL | needs_foo(());
| |
| required by a bound introduced by this call
|
help: this trait has no implementations, consider adding one
--> $DIR/where-clause-doesnt-apply.rs:2:1
|
LL | trait Bar {}
| ^^^^^^^^^
note: required for `()` to implement `Foo`
--> $DIR/where-clause-doesnt-apply.rs:4:9
|

View File

@ -2,13 +2,8 @@ error[E0271]: type mismatch resolving `<T as Foo>::Assoc == i32`
--> $DIR/param-candidate-shadows-project.rs:27:19
|
LL | require_bar::<T>();
| ^ type mismatch resolving `<T as Foo>::Assoc == i32`
| ^ types differ
|
note: types differ
--> $DIR/param-candidate-shadows-project.rs:10:18
|
LL | type Assoc = i32;
| ^^^
note: required for `T` to implement `Bar`
--> $DIR/param-candidate-shadows-project.rs:13:9
|

View File

@ -24,7 +24,7 @@ fn needs_bar<T: Bar>() {}
fn foo<T: Foo<Assoc = i32> + Foo<Assoc = u32>>() {
needs_bar::<T>();
//~^ ERROR type annotations needed: cannot satisfy `<T as Foo>::Assoc == i32`
//~^ ERROR type annotations needed: cannot normalize
}
fn main() {}

View File

@ -1,8 +1,8 @@
error[E0284]: type annotations needed: cannot satisfy `<T as Foo>::Assoc == i32`
error[E0284]: type annotations needed: cannot normalize `<T as Foo>::Assoc`
--> $DIR/two-projection-param-candidates-are-ambiguous.rs:26:17
|
LL | needs_bar::<T>();
| ^ cannot satisfy `<T as Foo>::Assoc == i32`
| ^ cannot normalize `<T as Foo>::Assoc`
|
note: required for `T` to implement `Bar`
--> $DIR/two-projection-param-candidates-are-ambiguous.rs:21:9

View File

@ -10,23 +10,23 @@ LL | #![feature(specialization)]
error: cannot normalize `<T as Default>::Id: '_`
error[E0284]: type annotations needed: cannot satisfy `<T as Default>::Id == _`
error[E0284]: type annotations needed: cannot normalize `<T as Default>::Id`
--> $DIR/specialization-transmute.rs:15:23
|
LL | fn intu(&self) -> &Self::Id {
| ^^^^^^^^^ cannot satisfy `<T as Default>::Id == _`
| ^^^^^^^^^ cannot normalize `<T as Default>::Id`
error[E0284]: type annotations needed: cannot satisfy `T <: <T as Default>::Id`
error[E0284]: type annotations needed: cannot satisfy `<T as Default>::Id normalizes-to T`
--> $DIR/specialization-transmute.rs:17:9
|
LL | self
| ^^^^ cannot satisfy `T <: <T as Default>::Id`
| ^^^^ cannot satisfy `<T as Default>::Id normalizes-to T`
error[E0284]: type annotations needed: cannot satisfy `<u8 as Default>::Id == Option<NonZero<u8>>`
error[E0284]: type annotations needed: cannot satisfy `<u8 as Default>::Id normalizes-to Option<NonZero<u8>>`
--> $DIR/specialization-transmute.rs:28:13
|
LL | let s = transmute::<u8, Option<NonZero<u8>>>(0);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot satisfy `<u8 as Default>::Id == Option<NonZero<u8>>`
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot satisfy `<u8 as Default>::Id normalizes-to Option<NonZero<u8>>`
|
note: required by a bound in `transmute`
--> $DIR/specialization-transmute.rs:21:25

View File

@ -18,5 +18,5 @@ fn test<T: Default<Id = U>, U>() {}
fn main() {
test::<u32, ()>();
//~^ ERROR cannot satisfy `<u32 as Default>::Id == ()`
//~^ ERROR cannot satisfy `<u32 as Default>::Id normalizes-to ()`
}

View File

@ -8,11 +8,11 @@ LL | #![feature(specialization)]
= help: consider using `min_specialization` instead, which is more stable and complete
= note: `#[warn(incomplete_features)]` on by default
error[E0284]: type annotations needed: cannot satisfy `<u32 as Default>::Id == ()`
error[E0284]: type annotations needed: cannot satisfy `<u32 as Default>::Id normalizes-to ()`
--> $DIR/specialization-unconstrained.rs:20:5
|
LL | test::<u32, ()>();
| ^^^^^^^^^^^^^^^^^ cannot satisfy `<u32 as Default>::Id == ()`
| ^^^^^^^^^^^^^^^^^ cannot satisfy `<u32 as Default>::Id normalizes-to ()`
|
note: required by a bound in `test`
--> $DIR/specialization-unconstrained.rs:17:20

View File

@ -2,7 +2,7 @@ error[E0277]: the trait bound `&char: Pattern<'_>` is not satisfied
--> $DIR/root-obligation.rs:6:38
|
LL | .filter(|c| "aeiou".contains(c))
| -------- ^ the trait `Fn(char)` is not implemented for `&char`, which is required by `&char: Pattern<'_>`
| -------- ^ the trait `Fn(char)` is not implemented for `char`, which is required by `&char: Pattern<'_>`
| |
| required by a bound introduced by this call
|

View File

@ -0,0 +1,26 @@
//@ check-pass
//! Tests that we do not regress rust-lang/rust#125811
#![feature(transmutability)]
fn assert_transmutable<T>()
where
(): std::mem::BikeshedIntrinsicFrom<T>
{}
enum Uninhabited {}
enum SingleInhabited {
X,
Y(Uninhabited)
}
enum SingleUninhabited {
X(Uninhabited),
Y(Uninhabited),
}
fn main() {
assert_transmutable::<Uninhabited>();
assert_transmutable::<SingleInhabited>();
assert_transmutable::<SingleUninhabited>();
}

View File

@ -2,7 +2,7 @@ error[E0277]: `&u8` cannot be safely transmuted into `&UnsafeCell<u8>`
--> $DIR/unsafecell.rs:27:50
|
LL | assert::is_maybe_transmutable::<&'static u8, &'static UnsafeCell<u8>>();
| ^^^^^^^^^^^^^^^^^^^^^^^ the trait `Freeze` is not implemented for `&'static UnsafeCell<u8>`
| ^^^^^^^^^^^^^^^^^^^^^^^ the trait `Freeze` is not implemented for `UnsafeCell<u8>`
|
note: required by a bound in `is_maybe_transmutable`
--> $DIR/unsafecell.rs:12:14
@ -17,7 +17,7 @@ error[E0277]: `&UnsafeCell<u8>` cannot be safely transmuted into `&UnsafeCell<u8
--> $DIR/unsafecell.rs:29:62
|
LL | assert::is_maybe_transmutable::<&'static UnsafeCell<u8>, &'static UnsafeCell<u8>>();
| ^^^^^^^^^^^^^^^^^^^^^^^ the trait `Freeze` is not implemented for `&'static UnsafeCell<u8>`
| ^^^^^^^^^^^^^^^^^^^^^^^ the trait `Freeze` is not implemented for `UnsafeCell<u8>`
|
note: required by a bound in `is_maybe_transmutable`
--> $DIR/unsafecell.rs:12:14

View File

@ -1,4 +1,4 @@
error[E0284]: type annotations needed: cannot satisfy `<Out as Trait<Bar, In>>::Out == ()`
error[E0284]: type annotations needed: cannot satisfy `Bar == _`
--> $DIR/issue-84660-unsoundness.rs:22:37
|
LL | fn convert(_i: In) -> Self::Out {
@ -7,7 +7,7 @@ LL | |
LL | |
LL | | unreachable!();
LL | | }
| |_____^ cannot satisfy `<Out as Trait<Bar, In>>::Out == ()`
| |_____^ cannot satisfy `Bar == _`
error[E0119]: conflicting implementations of trait `Trait<Bar, _>`
--> $DIR/issue-84660-unsoundness.rs:29:1

View File

@ -20,7 +20,7 @@ trait Trait<T, In> {
impl<In, Out> Trait<Bar, In> for Out {
type Out = Out;
fn convert(_i: In) -> Self::Out {
//[next]~^ ERROR: cannot satisfy `<Out as Trait<Bar, In>>::Out == ()`
//[next]~^ ERROR: cannot satisfy `Bar == _`
//[current]~^^ ERROR: item does not constrain `Bar::{opaque#0}`, but has it in its signature
unreachable!();
}

View File

@ -0,0 +1,16 @@
trait Foo<'s> {}
impl<'s> Foo<'s> for () {}
struct Bar;
impl<'s, T: Foo<'s>> From<T> for Bar {
fn from(_: T) -> Self {
Bar
}
}
fn main() {
let _: Bar = ((),).into();
//~^ ERROR he trait bound `((),): Into<Bar>` is not satisfied
}

View File

@ -0,0 +1,20 @@
error[E0277]: the trait bound `((),): Into<Bar>` is not satisfied
--> $DIR/suggest-similar-impls-for-root-obligation.rs:14:24
|
LL | let _: Bar = ((),).into();
| ^^^^ the trait `Foo<'_>` is not implemented for `((),)`, which is required by `((),): Into<_>`
|
= help: the trait `Foo<'_>` is implemented for `()`
= help: for that trait implementation, expected `()`, found `((),)`
note: required for `Bar` to implement `From<((),)>`
--> $DIR/suggest-similar-impls-for-root-obligation.rs:7:22
|
LL | impl<'s, T: Foo<'s>> From<T> for Bar {
| ------- ^^^^^^^ ^^^
| |
| unsatisfied trait bound introduced here
= note: required for `((),)` to implement `Into<Bar>`
error: aborting due to 1 previous error
For more information about this error, try `rustc --explain E0277`.