Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rollup of 8 pull requests #98521

Merged
merged 18 commits into from
Jun 26, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
9033576
Work around llvm 12's memory ordering restrictions.
m-ou-se Jun 22, 2022
20cea3e
Fix printing impl trait under binders
compiler-errors Jun 22, 2022
e80cced
Use write! instead of p! to avoid having to use weird scoping
compiler-errors Jun 22, 2022
9169905
x.py: Support systems with only `python3` not `python`
dtolnay Jun 25, 2022
557793c
Bump RLS to latest master on rust-lang/rls
Mark-Simulacrum Jun 25, 2022
50a46b9
Fix backtrace UI test when panic=abort is used
antoyo Jun 25, 2022
4c9e336
Fix CSS rule for selected and hovered items in the source sidebar
GuillaumeGomez Jun 25, 2022
2bb46be
Add test for source sidebar elements colors
GuillaumeGomez Jun 25, 2022
0ea59f3
diagnostics: consider parameter count when suggesting smart pointers
notriddle Jun 25, 2022
418b1fa
Fix LLVM rebuild with download-ci-llvm.
ehuss Jun 25, 2022
645e5c4
Rollup merge of #98371 - compiler-errors:better-opaque-printing, r=ol…
JohnTitor Jun 26, 2022
7c39776
Rollup merge of #98385 - m-ou-se:llvm-12-memory-order, r=petrochenkov
JohnTitor Jun 26, 2022
e1862ca
Rollup merge of #98474 - dtolnay:python3, r=Mark-Simulacrum
JohnTitor Jun 26, 2022
d0828a3
Rollup merge of #98488 - Mark-Simulacrum:bump-rls, r=pietroalbini
JohnTitor Jun 26, 2022
b1d66d8
Rollup merge of #98491 - antoyo:fix/ui-test-backtrace-panic-abort, r=…
JohnTitor Jun 26, 2022
d774bc3
Rollup merge of #98502 - GuillaumeGomez:source-sidebar-hover, r=notri…
JohnTitor Jun 26, 2022
c3b2291
Rollup merge of #98509 - rust-lang:notriddle/precise-pin-diag, r=comp…
JohnTitor Jun 26, 2022
fba8dfd
Rollup merge of #98513 - ehuss:rebuild-llvm-download, r=Mark-Simulacrum
JohnTitor Jun 26, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3054,7 +3054,6 @@ name = "racer"
version = "2.2.2"
dependencies = [
"bitflags",
"clap 2.34.0",
"derive_more",
"env_logger 0.7.1",
"humantime 2.0.1",
Expand Down Expand Up @@ -3278,7 +3277,7 @@ dependencies = [
"difference",
"env_logger 0.9.0",
"futures 0.3.19",
"heck 0.3.1",
"heck 0.4.0",
"home",
"itertools",
"jsonrpc-core",
Expand Down
16 changes: 15 additions & 1 deletion compiler/rustc_codegen_llvm/src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1064,11 +1064,25 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
dst: &'ll Value,
cmp: &'ll Value,
src: &'ll Value,
order: rustc_codegen_ssa::common::AtomicOrdering,
mut order: rustc_codegen_ssa::common::AtomicOrdering,
failure_order: rustc_codegen_ssa::common::AtomicOrdering,
weak: bool,
) -> &'ll Value {
let weak = if weak { llvm::True } else { llvm::False };
if llvm_util::get_version() < (13, 0, 0) {
use rustc_codegen_ssa::common::AtomicOrdering::*;
// Older llvm has the pre-C++17 restriction on
// success and failure memory ordering,
// requiring the former to be at least as strong as the latter.
// So, for llvm 12, we upgrade the success ordering to a stronger
// one if necessary.
match (order, failure_order) {
(Relaxed, Acquire) => order = Acquire,
(Release, Acquire) => order = AcquireRelease,
(_, SequentiallyConsistent) => order = SequentiallyConsistent,
_ => {}
}
}
unsafe {
llvm::LLVMRustBuildAtomicCmpXchg(
self.llbuilder,
Expand Down
233 changes: 120 additions & 113 deletions compiler/rustc_middle/src/ty/print/pretty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ pub trait PrettyPrinter<'tcx>:
value.as_ref().skip_binder().print(self)
}

fn wrap_binder<T, F: Fn(&T, Self) -> Result<Self, fmt::Error>>(
fn wrap_binder<T, F: FnOnce(&T, Self) -> Result<Self, fmt::Error>>(
self,
value: &ty::Binder<'tcx, T>,
f: F,
Expand Down Expand Up @@ -773,26 +773,26 @@ pub trait PrettyPrinter<'tcx>:
def_id: DefId,
substs: &'tcx ty::List<ty::GenericArg<'tcx>>,
) -> Result<Self::Type, Self::Error> {
define_scoped_cx!(self);
let tcx = self.tcx();

// Grab the "TraitA + TraitB" from `impl TraitA + TraitB`,
// by looking up the projections associated with the def_id.
let bounds = self.tcx().bound_explicit_item_bounds(def_id);
let bounds = tcx.bound_explicit_item_bounds(def_id);

let mut traits = FxIndexMap::default();
let mut fn_traits = FxIndexMap::default();
let mut is_sized = false;

for predicate in bounds.transpose_iter().map(|e| e.map_bound(|(p, _)| *p)) {
let predicate = predicate.subst(self.tcx(), substs);
let predicate = predicate.subst(tcx, substs);
let bound_predicate = predicate.kind();

match bound_predicate.skip_binder() {
ty::PredicateKind::Trait(pred) => {
let trait_ref = bound_predicate.rebind(pred.trait_ref);

// Don't print + Sized, but rather + ?Sized if absent.
if Some(trait_ref.def_id()) == self.tcx().lang_items().sized_trait() {
if Some(trait_ref.def_id()) == tcx.lang_items().sized_trait() {
is_sized = true;
continue;
}
Expand All @@ -801,7 +801,7 @@ pub trait PrettyPrinter<'tcx>:
}
ty::PredicateKind::Projection(pred) => {
let proj_ref = bound_predicate.rebind(pred);
let trait_ref = proj_ref.required_poly_trait_ref(self.tcx());
let trait_ref = proj_ref.required_poly_trait_ref(tcx);

// Projection type entry -- the def-id for naming, and the ty.
let proj_ty = (proj_ref.projection_def_id(), proj_ref.term());
Expand All @@ -817,148 +817,155 @@ pub trait PrettyPrinter<'tcx>:
}
}

write!(self, "impl ")?;

let mut first = true;
// Insert parenthesis around (Fn(A, B) -> C) if the opaque ty has more than one other trait
let paren_needed = fn_traits.len() > 1 || traits.len() > 0 || !is_sized;

p!("impl");

for (fn_once_trait_ref, entry) in fn_traits {
// Get the (single) generic ty (the args) of this FnOnce trait ref.
let generics = self.tcx().generics_of(fn_once_trait_ref.def_id());
let args =
generics.own_substs_no_defaults(self.tcx(), fn_once_trait_ref.skip_binder().substs);

match (entry.return_ty, args[0].expect_ty()) {
// We can only print `impl Fn() -> ()` if we have a tuple of args and we recorded
// a return type.
(Some(return_ty), arg_tys) if matches!(arg_tys.kind(), ty::Tuple(_)) => {
let name = if entry.fn_trait_ref.is_some() {
"Fn"
} else if entry.fn_mut_trait_ref.is_some() {
"FnMut"
} else {
"FnOnce"
};
write!(self, "{}", if first { "" } else { " + " })?;
write!(self, "{}", if paren_needed { "(" } else { "" })?;

p!(
write("{}", if first { " " } else { " + " }),
write("{}{}(", if paren_needed { "(" } else { "" }, name)
);
self = self.wrap_binder(&fn_once_trait_ref, |trait_ref, mut cx| {
define_scoped_cx!(cx);
// Get the (single) generic ty (the args) of this FnOnce trait ref.
let generics = tcx.generics_of(trait_ref.def_id);
let args = generics.own_substs_no_defaults(tcx, trait_ref.substs);

match (entry.return_ty, args[0].expect_ty()) {
// We can only print `impl Fn() -> ()` if we have a tuple of args and we recorded
// a return type.
(Some(return_ty), arg_tys) if matches!(arg_tys.kind(), ty::Tuple(_)) => {
let name = if entry.fn_trait_ref.is_some() {
"Fn"
} else if entry.fn_mut_trait_ref.is_some() {
"FnMut"
} else {
"FnOnce"
};

for (idx, ty) in arg_tys.tuple_fields().iter().enumerate() {
if idx > 0 {
p!(", ");
p!(write("{}(", name));

for (idx, ty) in arg_tys.tuple_fields().iter().enumerate() {
if idx > 0 {
p!(", ");
}
p!(print(ty));
}
p!(print(ty));
}

p!(")");
if let Term::Ty(ty) = return_ty.skip_binder() {
if !ty.is_unit() {
p!(" -> ", print(return_ty));
p!(")");
if let Term::Ty(ty) = return_ty.skip_binder() {
if !ty.is_unit() {
p!(" -> ", print(return_ty));
}
}
}
p!(write("{}", if paren_needed { ")" } else { "" }));
p!(write("{}", if paren_needed { ")" } else { "" }));

first = false;
}
// If we got here, we can't print as a `impl Fn(A, B) -> C`. Just record the
// trait_refs we collected in the OpaqueFnEntry as normal trait refs.
_ => {
if entry.has_fn_once {
traits.entry(fn_once_trait_ref).or_default().extend(
// Group the return ty with its def id, if we had one.
entry
.return_ty
.map(|ty| (self.tcx().lang_items().fn_once_output().unwrap(), ty)),
);
}
if let Some(trait_ref) = entry.fn_mut_trait_ref {
traits.entry(trait_ref).or_default();
first = false;
}
if let Some(trait_ref) = entry.fn_trait_ref {
traits.entry(trait_ref).or_default();
// If we got here, we can't print as a `impl Fn(A, B) -> C`. Just record the
// trait_refs we collected in the OpaqueFnEntry as normal trait refs.
_ => {
if entry.has_fn_once {
traits.entry(fn_once_trait_ref).or_default().extend(
// Group the return ty with its def id, if we had one.
entry
.return_ty
.map(|ty| (tcx.lang_items().fn_once_output().unwrap(), ty)),
);
}
if let Some(trait_ref) = entry.fn_mut_trait_ref {
traits.entry(trait_ref).or_default();
}
if let Some(trait_ref) = entry.fn_trait_ref {
traits.entry(trait_ref).or_default();
}
}
}
}

Ok(cx)
})?;
}

// Print the rest of the trait types (that aren't Fn* family of traits)
for (trait_ref, assoc_items) in traits {
p!(
write("{}", if first { " " } else { " + " }),
print(trait_ref.skip_binder().print_only_trait_name())
);
write!(self, "{}", if first { "" } else { " + " })?;

self = self.wrap_binder(&trait_ref, |trait_ref, mut cx| {
define_scoped_cx!(cx);
p!(print(trait_ref.print_only_trait_name()));

let generics = self.tcx().generics_of(trait_ref.def_id());
let args = generics.own_substs_no_defaults(self.tcx(), trait_ref.skip_binder().substs);
let generics = tcx.generics_of(trait_ref.def_id);
let args = generics.own_substs_no_defaults(tcx, trait_ref.substs);

if !args.is_empty() || !assoc_items.is_empty() {
let mut first = true;
if !args.is_empty() || !assoc_items.is_empty() {
let mut first = true;

for ty in args {
if first {
p!("<");
first = false;
} else {
p!(", ");
for ty in args {
if first {
p!("<");
first = false;
} else {
p!(", ");
}
p!(print(ty));
}
p!(print(trait_ref.rebind(*ty)));
}

for (assoc_item_def_id, term) in assoc_items {
// Skip printing `<[generator@] as Generator<_>>::Return` from async blocks,
// unless we can find out what generator return type it comes from.
let term = if let Some(ty) = term.skip_binder().ty()
&& let ty::Projection(ty::ProjectionTy { item_def_id, substs }) = ty.kind()
&& Some(*item_def_id) == self.tcx().lang_items().generator_return()
{
if let ty::Generator(_, substs, _) = substs.type_at(0).kind() {
let return_ty = substs.as_generator().return_ty();
if !return_ty.is_ty_infer() {
return_ty.into()
for (assoc_item_def_id, term) in assoc_items {
// Skip printing `<[generator@] as Generator<_>>::Return` from async blocks,
// unless we can find out what generator return type it comes from.
let term = if let Some(ty) = term.skip_binder().ty()
&& let ty::Projection(ty::ProjectionTy { item_def_id, substs }) = ty.kind()
&& Some(*item_def_id) == tcx.lang_items().generator_return()
{
if let ty::Generator(_, substs, _) = substs.type_at(0).kind() {
let return_ty = substs.as_generator().return_ty();
if !return_ty.is_ty_infer() {
return_ty.into()
} else {
continue;
}
} else {
continue;
}
} else {
continue;
}
} else {
term.skip_binder()
};
term.skip_binder()
};

if first {
p!("<");
first = false;
} else {
p!(", ");
}
if first {
p!("<");
first = false;
} else {
p!(", ");
}

p!(write("{} = ", self.tcx().associated_item(assoc_item_def_id).name));
p!(write("{} = ", tcx.associated_item(assoc_item_def_id).name));

match term {
Term::Ty(ty) => {
p!(print(ty))
}
Term::Const(c) => {
p!(print(c));
}
};
}
match term {
Term::Ty(ty) => {
p!(print(ty))
}
Term::Const(c) => {
p!(print(c));
}
};
}

if !first {
p!(">");
if !first {
p!(">");
}
}
}

first = false;
first = false;
Ok(cx)
})?;
}

if !is_sized {
p!(write("{}?Sized", if first { " " } else { " + " }));
write!(self, "{}?Sized", if first { "" } else { " + " })?;
} else if first {
p!(" Sized");
write!(self, "Sized")?;
}

Ok(self)
Expand Down Expand Up @@ -1869,7 +1876,7 @@ impl<'tcx> PrettyPrinter<'tcx> for FmtPrinter<'_, 'tcx> {
self.pretty_in_binder(value)
}

fn wrap_binder<T, C: Fn(&T, Self) -> Result<Self, Self::Error>>(
fn wrap_binder<T, C: FnOnce(&T, Self) -> Result<Self, Self::Error>>(
self,
value: &ty::Binder<'tcx, T>,
f: C,
Expand Down Expand Up @@ -2256,7 +2263,7 @@ impl<'tcx> FmtPrinter<'_, 'tcx> {
Ok(inner)
}

pub fn pretty_wrap_binder<T, C: Fn(&T, Self) -> Result<Self, fmt::Error>>(
pub fn pretty_wrap_binder<T, C: FnOnce(&T, Self) -> Result<Self, fmt::Error>>(
self,
value: &ty::Binder<'tcx, T>,
f: C,
Expand Down
5 changes: 4 additions & 1 deletion compiler/rustc_typeck/src/check/method/suggest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -994,6 +994,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
span,
rcvr_ty,
item_name,
args.map(|args| args.len()),
source,
out_of_scope_traits,
&unsatisfied_predicates,
Expand Down Expand Up @@ -1732,6 +1733,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
span: Span,
rcvr_ty: Ty<'tcx>,
item_name: Ident,
inputs_len: Option<usize>,
source: SelfSource<'tcx>,
valid_out_of_scope_traits: Vec<DefId>,
unsatisfied_predicates: &[(
Expand Down Expand Up @@ -1808,7 +1810,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// Explicitly ignore the `Pin::as_ref()` method as `Pin` does not
// implement the `AsRef` trait.
let skip = skippable.contains(&did)
|| (("Pin::new" == *pre) && (sym::as_ref == item_name.name));
|| (("Pin::new" == *pre) && (sym::as_ref == item_name.name))
|| inputs_len.map_or(false, |inputs_len| pick.item.kind == ty::AssocKind::Fn && self.tcx.fn_sig(pick.item.def_id).skip_binder().inputs().len() != inputs_len);
// Make sure the method is defined for the *actual* receiver: we don't
// want to treat `Box<Self>` as a receiver if it only works because of
// an autoderef to `&self`
Expand Down
Loading