Skip to content

Commit

Permalink
Auto merge of rust-lang#93352 - matthiaskrgr:rollup-5peret4, r=matthi…
Browse files Browse the repository at this point in the history
…askrgr

Rollup of 7 pull requests

Successful merges:

 - rust-lang#90247 (Improve Duration::try_from_secs_f32/64 accuracy by directly processing exponent and mantissa)
 - rust-lang#91861 (Replace iterator-based construction of collections by `Into<T>`)
 - rust-lang#92098 (add OpenBSD platform-support page)
 - rust-lang#92134 (Add x86_64-pc-windows-msvc linker-plugin-lto instructions)
 - rust-lang#92256 (Improve selection errors for `~const` trait bounds)
 - rust-lang#92778 (fs: Use readdir() instead of readdir_r() on Linux and Android)
 - rust-lang#93338 (Update minifier crate version to 0.0.42)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
  • Loading branch information
bors committed Jan 26, 2022
2 parents 6abb638 + 4276626 commit 009c1d0
Show file tree
Hide file tree
Showing 41 changed files with 829 additions and 404 deletions.
4 changes: 2 additions & 2 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2298,9 +2298,9 @@ dependencies = [

[[package]]
name = "minifier"
version = "0.0.41"
version = "0.0.42"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5594542d20834f2b974f5e5fb8e0cf1c67a2119dcadc29ef5d93a081fb30cc08"
checksum = "55a1388517eda8a68875243b650c26997e055a33d82571b5a0349129faef7d99"
dependencies = [
"macro-utils",
]
Expand Down
8 changes: 4 additions & 4 deletions compiler/rustc_middle/src/traits/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -402,7 +402,7 @@ impl ObligationCauseCode<'_> {

// `ObligationCauseCode` is used a lot. Make sure it doesn't unintentionally get bigger.
#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
static_assert_size!(ObligationCauseCode<'_>, 40);
static_assert_size!(ObligationCauseCode<'_>, 48);

#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
pub enum StatementAsExpression {
Expand Down Expand Up @@ -440,11 +440,11 @@ pub struct IfExpressionCause {

#[derive(Clone, Debug, PartialEq, Eq, Hash, Lift)]
pub struct DerivedObligationCause<'tcx> {
/// The trait reference of the parent obligation that led to the
/// The trait predicate of the parent obligation that led to the
/// current obligation. Note that only trait obligations lead to
/// derived obligations, so we just store the trait reference here
/// derived obligations, so we just store the trait predicate here
/// directly.
pub parent_trait_ref: ty::PolyTraitRef<'tcx>,
pub parent_trait_pred: ty::PolyTraitPredicate<'tcx>,

/// The parent trait had this cause.
pub parent_code: Lrc<ObligationCauseCode<'tcx>>,
Expand Down
19 changes: 19 additions & 0 deletions compiler/rustc_middle/src/ty/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -766,6 +766,17 @@ impl<'tcx> TraitPredicate<'tcx> {
*param_env = param_env.with_constness(self.constness.and(param_env.constness()))
}
}

/// Remap the constness of this predicate before emitting it for diagnostics.
pub fn remap_constness_diag(&mut self, param_env: ParamEnv<'tcx>) {
// this is different to `remap_constness` that callees want to print this predicate
// in case of selection errors. `T: ~const Drop` bounds cannot end up here when the
// param_env is not const because we it is always satisfied in non-const contexts.
if let hir::Constness::NotConst = param_env.constness() {
self.constness = ty::BoundConstness::NotConst;
}
}

pub fn def_id(self) -> DefId {
self.trait_ref.def_id
}
Expand All @@ -784,6 +795,14 @@ impl<'tcx> PolyTraitPredicate<'tcx> {
pub fn self_ty(self) -> ty::Binder<'tcx, Ty<'tcx>> {
self.map_bound(|trait_ref| trait_ref.self_ty())
}

/// Remap the constness of this predicate before emitting it for diagnostics.
pub fn remap_constness_diag(&mut self, param_env: ParamEnv<'tcx>) {
*self = self.map_bound(|mut p| {
p.remap_constness_diag(param_env);
p
});
}
}

#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, TyEncodable, TyDecodable)]
Expand Down
43 changes: 41 additions & 2 deletions compiler/rustc_middle/src/ty/print/pretty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2413,6 +2413,29 @@ impl<'tcx> ty::Binder<'tcx, ty::TraitRef<'tcx>> {
}
}

#[derive(Copy, Clone, TypeFoldable, Lift)]
pub struct TraitPredPrintModifiersAndPath<'tcx>(ty::TraitPredicate<'tcx>);

impl<'tcx> fmt::Debug for TraitPredPrintModifiersAndPath<'tcx> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Display::fmt(self, f)
}
}

impl<'tcx> ty::TraitPredicate<'tcx> {
pub fn print_modifiers_and_trait_path(self) -> TraitPredPrintModifiersAndPath<'tcx> {
TraitPredPrintModifiersAndPath(self)
}
}

impl<'tcx> ty::PolyTraitPredicate<'tcx> {
pub fn print_modifiers_and_trait_path(
self,
) -> ty::Binder<'tcx, TraitPredPrintModifiersAndPath<'tcx>> {
self.map_bound(TraitPredPrintModifiersAndPath)
}
}

forward_display_to_print! {
Ty<'tcx>,
&'tcx ty::List<ty::Binder<'tcx, ty::ExistentialPredicate<'tcx>>>,
Expand All @@ -2427,6 +2450,7 @@ forward_display_to_print! {
ty::Binder<'tcx, TraitRefPrintOnlyTraitName<'tcx>>,
ty::Binder<'tcx, ty::FnSig<'tcx>>,
ty::Binder<'tcx, ty::TraitPredicate<'tcx>>,
ty::Binder<'tcx, TraitPredPrintModifiersAndPath<'tcx>>,
ty::Binder<'tcx, ty::SubtypePredicate<'tcx>>,
ty::Binder<'tcx, ty::ProjectionPredicate<'tcx>>,
ty::Binder<'tcx, ty::OutlivesPredicate<Ty<'tcx>, ty::Region<'tcx>>>,
Expand Down Expand Up @@ -2491,6 +2515,18 @@ define_print_and_forward_display! {
p!(print_def_path(self.0.def_id, &[]));
}

TraitPredPrintModifiersAndPath<'tcx> {
if let ty::BoundConstness::ConstIfConst = self.0.constness {
p!("~const ")
}

if let ty::ImplPolarity::Negative = self.0.polarity {
p!("!")
}

p!(print(self.0.trait_ref.print_only_trait_path()));
}

ty::ParamTy {
p!(write("{}", self.name))
}
Expand All @@ -2508,8 +2544,11 @@ define_print_and_forward_display! {
}

ty::TraitPredicate<'tcx> {
p!(print(self.trait_ref.self_ty()), ": ",
print(self.trait_ref.print_only_trait_path()))
p!(print(self.trait_ref.self_ty()), ": ");
if let ty::BoundConstness::ConstIfConst = self.constness {
p!("~const ");
}
p!(print(self.trait_ref.print_only_trait_path()))
}

ty::ProjectionPredicate<'tcx> {
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_span/src/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,7 @@ symbols! {
and,
and_then,
any,
append_const_msg,
arbitrary_enum_discriminant,
arbitrary_self_types,
arith_offset,
Expand Down
99 changes: 68 additions & 31 deletions compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
self.note_obligation_cause_code(
&mut err,
&obligation.predicate,
obligation.param_env,
obligation.cause.code(),
&mut vec![],
&mut Default::default(),
Expand Down Expand Up @@ -288,7 +289,11 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
match bound_predicate.skip_binder() {
ty::PredicateKind::Trait(trait_predicate) => {
let trait_predicate = bound_predicate.rebind(trait_predicate);
let trait_predicate = self.resolve_vars_if_possible(trait_predicate);
let mut trait_predicate = self.resolve_vars_if_possible(trait_predicate);

trait_predicate.remap_constness_diag(obligation.param_env);
let predicate_is_const = ty::BoundConstness::ConstIfConst
== trait_predicate.skip_binder().constness;

if self.tcx.sess.has_errors() && trait_predicate.references_error() {
return;
Expand All @@ -305,13 +310,18 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
})
.unwrap_or_default();

let OnUnimplementedNote { message, label, note, enclosing_scope } =
self.on_unimplemented_note(trait_ref, &obligation);
let OnUnimplementedNote {
message,
label,
note,
enclosing_scope,
append_const_msg,
} = self.on_unimplemented_note(trait_ref, &obligation);
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_unsize =
{ Some(trait_ref.def_id()) == self.tcx.lang_items().unsize_trait() };
let (message, note) = if is_try_conversion {
let (message, note, append_const_msg) = if is_try_conversion {
(
Some(format!(
"`?` couldn't convert the error to `{}`",
Expand All @@ -322,21 +332,38 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
conversion on the error value using the `From` trait"
.to_owned(),
),
Some(None),
)
} else {
(message, note)
(message, note, append_const_msg)
};

let mut err = struct_span_err!(
self.tcx.sess,
span,
E0277,
"{}",
message.unwrap_or_else(|| format!(
"the trait bound `{}` is not satisfied{}",
trait_ref.without_const().to_predicate(tcx),
post_message,
))
message
.and_then(|cannot_do_this| {
match (predicate_is_const, append_const_msg) {
// do nothing if predicate is not const
(false, _) => Some(cannot_do_this),
// suggested using default post message
(true, Some(None)) => {
Some(format!("{cannot_do_this} in const contexts"))
}
// overriden post message
(true, Some(Some(post_message))) => {
Some(format!("{cannot_do_this}{post_message}"))
}
// fallback to generic message
(true, None) => None,
}
})
.unwrap_or_else(|| format!(
"the trait bound `{}` is not satisfied{}",
trait_predicate, post_message,
))
);

if is_try_conversion {
Expand Down Expand Up @@ -384,15 +411,15 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
format!(
"{}the trait `{}` is not implemented for `{}`",
pre_message,
trait_ref.print_only_trait_path(),
trait_predicate.print_modifiers_and_trait_path(),
trait_ref.skip_binder().self_ty(),
)
};

if self.suggest_add_reference_to_arg(
&obligation,
&mut err,
&trait_ref,
trait_predicate,
have_alt_message,
) {
self.note_obligation_cause(&mut err, &obligation);
Expand Down Expand Up @@ -435,18 +462,28 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
err.span_label(enclosing_scope_span, s.as_str());
}

self.suggest_dereferences(&obligation, &mut err, trait_ref);
self.suggest_fn_call(&obligation, &mut err, trait_ref);
self.suggest_remove_reference(&obligation, &mut err, trait_ref);
self.suggest_semicolon_removal(&obligation, &mut err, span, trait_ref);
self.suggest_dereferences(&obligation, &mut err, trait_predicate);
self.suggest_fn_call(&obligation, &mut err, trait_predicate);
self.suggest_remove_reference(&obligation, &mut err, trait_predicate);
self.suggest_semicolon_removal(
&obligation,
&mut err,
span,
trait_predicate,
);
self.note_version_mismatch(&mut err, &trait_ref);
self.suggest_remove_await(&obligation, &mut err);

if Some(trait_ref.def_id()) == tcx.lang_items().try_trait() {
self.suggest_await_before_try(&mut err, &obligation, trait_ref, span);
self.suggest_await_before_try(
&mut err,
&obligation,
trait_predicate,
span,
);
}

if self.suggest_impl_trait(&mut err, span, &obligation, trait_ref) {
if self.suggest_impl_trait(&mut err, span, &obligation, trait_predicate) {
err.emit();
return;
}
Expand Down Expand Up @@ -494,7 +531,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
// which is somewhat confusing.
self.suggest_restricting_param_bound(
&mut err,
trait_ref,
trait_predicate,
obligation.cause.body_id,
);
} else if !have_alt_message {
Expand All @@ -506,7 +543,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, '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_ref);
self.suggest_change_mut(&obligation, &mut err, trait_predicate);
}

// If this error is due to `!: Trait` not implemented but `(): Trait` is
Expand Down Expand Up @@ -1121,7 +1158,7 @@ trait InferCtxtPrivExt<'hir, 'tcx> {
fn mk_trait_obligation_with_new_self_ty(
&self,
param_env: ty::ParamEnv<'tcx>,
trait_ref: ty::PolyTraitRef<'tcx>,
trait_ref: ty::PolyTraitPredicate<'tcx>,
new_self_ty: Ty<'tcx>,
) -> PredicateObligation<'tcx>;

Expand Down Expand Up @@ -1541,7 +1578,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
) -> Option<(String, Option<Span>)> {
match code {
ObligationCauseCode::BuiltinDerivedObligation(data) => {
let parent_trait_ref = self.resolve_vars_if_possible(data.parent_trait_ref);
let parent_trait_ref = self.resolve_vars_if_possible(data.parent_trait_pred);
match self.get_parent_trait_ref(&data.parent_code) {
Some(t) => Some(t),
None => {
Expand Down Expand Up @@ -1594,21 +1631,20 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
fn mk_trait_obligation_with_new_self_ty(
&self,
param_env: ty::ParamEnv<'tcx>,
trait_ref: ty::PolyTraitRef<'tcx>,
trait_ref: ty::PolyTraitPredicate<'tcx>,
new_self_ty: Ty<'tcx>,
) -> PredicateObligation<'tcx> {
assert!(!new_self_ty.has_escaping_bound_vars());

let trait_ref = trait_ref.map_bound_ref(|tr| ty::TraitRef {
substs: self.tcx.mk_substs_trait(new_self_ty, &tr.substs[1..]),
let trait_pred = trait_ref.map_bound_ref(|tr| ty::TraitPredicate {
trait_ref: ty::TraitRef {
substs: self.tcx.mk_substs_trait(new_self_ty, &tr.trait_ref.substs[1..]),
..tr.trait_ref
},
..*tr
});

Obligation::new(
ObligationCause::dummy(),
param_env,
trait_ref.without_const().to_predicate(self.tcx),
)
Obligation::new(ObligationCause::dummy(), param_env, trait_pred.to_predicate(self.tcx))
}

#[instrument(skip(self), level = "debug")]
Expand Down Expand Up @@ -2009,6 +2045,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
self.note_obligation_cause_code(
err,
&obligation.predicate,
obligation.param_env,
obligation.cause.code(),
&mut vec![],
&mut Default::default(),
Expand Down Expand Up @@ -2156,7 +2193,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
cause_code: &ObligationCauseCode<'tcx>,
) -> bool {
if let ObligationCauseCode::BuiltinDerivedObligation(ref data) = cause_code {
let parent_trait_ref = self.resolve_vars_if_possible(data.parent_trait_ref);
let parent_trait_ref = self.resolve_vars_if_possible(data.parent_trait_pred);
let self_ty = parent_trait_ref.skip_binder().self_ty();
if obligated_types.iter().any(|ot| ot == &self_ty) {
return true;
Expand Down
Loading

0 comments on commit 009c1d0

Please sign in to comment.