Skip to content

Rollup of 8 pull requests #96427

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

Closed
wants to merge 19 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
9f4934e
Clarify that `Cow::into_owned` returns owned data
jongiddy Mar 23, 2022
8d5a496
Implement Default for AssertUnwindSafe
SoniEx2 Apr 11, 2022
352abba
Fix a bug in the ptx-kernel calling convention where structs was pass…
kjetilkjeka Mar 7, 2022
4280c81
Update search.js to ES6
GuillaumeGomez Apr 24, 2022
3c95c0b
Update settings.js to ES6
GuillaumeGomez Apr 24, 2022
0233abe
Update rustdoc-js tester tool to work with new kind of variables
GuillaumeGomez Apr 24, 2022
dff7f25
suggestion if struct field has method
compiler-errors Apr 24, 2022
74853ee
simplify `describe_field` func in borrowck's diagnostics part
SparrowLii Apr 25, 2022
5bf5acc
Add test for asserting correct generation of ptx-kernel args
kjetilkjeka Mar 7, 2022
941e194
Correct documentation for `ShallowInitBox`
JakobDegen Apr 25, 2022
159b95d
Remove references to git.io
ehuss Apr 26, 2022
24dcda0
Rollup merge of #94022 - jongiddy:cow-into-owned-docs, r=Dylan-DPC
GuillaumeGomez Apr 26, 2022
f1fbc71
Rollup merge of #94703 - kjetilkjeka:nvptx-kernel-args-abi2, r=nagisa
GuillaumeGomez Apr 26, 2022
8621a2f
Rollup merge of #95949 - SoniEx2:patch-5, r=m-ou-se
GuillaumeGomez Apr 26, 2022
77e607e
Rollup merge of #96361 - GuillaumeGomez:es6, r=notriddle
GuillaumeGomez Apr 26, 2022
8b71be8
Rollup merge of #96372 - compiler-errors:field-method-suggest, r=oli-obk
GuillaumeGomez Apr 26, 2022
1c1b418
Rollup merge of #96386 - SparrowLii:des_field, r=jackh726
GuillaumeGomez Apr 26, 2022
5c026e3
Rollup merge of #96400 - JakobDegen:shallow-init-docs, r=Dylan-DPC
GuillaumeGomez Apr 26, 2022
898059c
Rollup merge of #96415 - ehuss:git-io, r=bjorn3
GuillaumeGomez Apr 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
29 changes: 10 additions & 19 deletions compiler/rustc_borrowck/src/diagnostics/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ crate use outlives_suggestion::OutlivesSuggestionBuilder;
crate use region_errors::{ErrorConstraintInfo, RegionErrorKind, RegionErrors};
crate use region_name::{RegionName, RegionNameSource};
crate use rustc_const_eval::util::CallKind;
use rustc_middle::mir::tcx::PlaceTy;

pub(super) struct IncludingDowncast(pub(super) bool);

Expand Down Expand Up @@ -329,30 +330,20 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {

/// End-user visible description of the `field`nth field of `base`
fn describe_field(&self, place: PlaceRef<'tcx>, field: Field) -> String {
// FIXME Place2 Make this work iteratively
match place {
PlaceRef { local, projection: [] } => {
let local = &self.body.local_decls[local];
self.describe_field_from_ty(local.ty, field, None)
}
let place_ty = match place {
PlaceRef { local, projection: [] } => PlaceTy::from_ty(self.body.local_decls[local].ty),
PlaceRef { local, projection: [proj_base @ .., elem] } => match elem {
ProjectionElem::Deref => {
self.describe_field(PlaceRef { local, projection: proj_base }, field)
}
ProjectionElem::Downcast(_, variant_index) => {
let base_ty = place.ty(self.body, self.infcx.tcx).ty;
self.describe_field_from_ty(base_ty, field, Some(*variant_index))
}
ProjectionElem::Field(_, field_type) => {
self.describe_field_from_ty(*field_type, field, None)
}
ProjectionElem::Index(..)
ProjectionElem::Deref
| ProjectionElem::Index(..)
| ProjectionElem::ConstantIndex { .. }
| ProjectionElem::Subslice { .. } => {
self.describe_field(PlaceRef { local, projection: proj_base }, field)
PlaceRef { local, projection: proj_base }.ty(self.body, self.infcx.tcx)
}
ProjectionElem::Downcast(..) => place.ty(self.body, self.infcx.tcx),
ProjectionElem::Field(_, field_type) => PlaceTy::from_ty(*field_type),
},
}
};
self.describe_field_from_ty(place_ty.ty, field, place_ty.variant_index)
}

/// End-user visible description of the `field_index`nth field of `ty`
Expand Down
2 changes: 0 additions & 2 deletions compiler/rustc_middle/src/mir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2581,8 +2581,6 @@ pub enum Rvalue<'tcx> {
/// This is different from a normal transmute because dataflow analysis will treat the box as
/// initialized but its content as uninitialized. Like other pointer casts, this in general
/// affects alias analysis.
///
/// Disallowed after drop elaboration.
ShallowInitBox(Operand<'tcx>, Ty<'tcx>),
}

Expand Down
16 changes: 16 additions & 0 deletions compiler/rustc_middle/src/ty/layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2592,6 +2592,22 @@ where

pointee_info
}

fn is_adt(this: TyAndLayout<'tcx>) -> bool {
matches!(this.ty.kind(), ty::Adt(..))
}

fn is_never(this: TyAndLayout<'tcx>) -> bool {
this.ty.kind() == &ty::Never
}

fn is_tuple(this: TyAndLayout<'tcx>) -> bool {
matches!(this.ty.kind(), ty::Tuple(..))
}

fn is_unit(this: TyAndLayout<'tcx>) -> bool {
matches!(this.ty.kind(), ty::Tuple(list) if list.len() == 0)
}
}

impl<'tcx> ty::Instance<'tcx> {
Expand Down
4 changes: 4 additions & 0 deletions compiler/rustc_middle/src/ty/list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,10 @@ impl<T> List<T> {
static EMPTY_SLICE: InOrder<usize, MaxAlign> = InOrder(0, MaxAlign);
unsafe { &*(&EMPTY_SLICE as *const _ as *const List<T>) }
}

pub fn len(&self) -> usize {
self.len
}
}

impl<T: Copy> List<T> {
Expand Down
8 changes: 7 additions & 1 deletion compiler/rustc_target/src/abi/call/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -696,7 +696,13 @@ impl<'a, Ty> FnAbi<'a, Ty> {
"sparc" => sparc::compute_abi_info(cx, self),
"sparc64" => sparc64::compute_abi_info(cx, self),
"nvptx" => nvptx::compute_abi_info(self),
"nvptx64" => nvptx64::compute_abi_info(self),
"nvptx64" => {
if cx.target_spec().adjust_abi(abi) == spec::abi::Abi::PtxKernel {
nvptx64::compute_ptx_kernel_abi_info(cx, self)
} else {
nvptx64::compute_abi_info(self)
}
}
"hexagon" => hexagon::compute_abi_info(self),
"riscv32" | "riscv64" => riscv::compute_abi_info(cx, self),
"wasm32" | "wasm64" => {
Expand Down
47 changes: 39 additions & 8 deletions compiler/rustc_target/src/abi/call/nvptx64.rs
Original file line number Diff line number Diff line change
@@ -1,21 +1,35 @@
// Reference: PTX Writer's Guide to Interoperability
// https://docs.nvidia.com/cuda/ptx-writers-guide-to-interoperability

use crate::abi::call::{ArgAbi, FnAbi};
use crate::abi::call::{ArgAbi, FnAbi, PassMode, Reg, Size, Uniform};
use crate::abi::{HasDataLayout, TyAbiInterface};

fn classify_ret<Ty>(ret: &mut ArgAbi<'_, Ty>) {
if ret.layout.is_aggregate() && ret.layout.size.bits() > 64 {
ret.make_indirect();
} else {
ret.extend_integer_width_to(64);
}
}

fn classify_arg<Ty>(arg: &mut ArgAbi<'_, Ty>) {
if arg.layout.is_aggregate() && arg.layout.size.bits() > 64 {
arg.make_indirect();
} else {
arg.extend_integer_width_to(64);
}
}

fn classify_arg_kernel<'a, Ty, C>(_cx: &C, arg: &mut ArgAbi<'a, Ty>)
where
Ty: TyAbiInterface<'a, C> + Copy,
C: HasDataLayout,
{
if matches!(arg.mode, PassMode::Pair(..)) && (arg.layout.is_adt() || arg.layout.is_tuple()) {
let align_bytes = arg.layout.align.abi.bytes();

let unit = match align_bytes {
1 => Reg::i8(),
2 => Reg::i16(),
4 => Reg::i32(),
8 => Reg::i64(),
16 => Reg::i128(),
_ => unreachable!("Align is given as power of 2 no larger than 16 bytes"),
};
arg.cast_to(Uniform { unit, total: Size::from_bytes(2 * align_bytes) });
}
}

Expand All @@ -31,3 +45,20 @@ pub fn compute_abi_info<Ty>(fn_abi: &mut FnAbi<'_, Ty>) {
classify_arg(arg);
}
}

pub fn compute_ptx_kernel_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>)
where
Ty: TyAbiInterface<'a, C> + Copy,
C: HasDataLayout,
{
if !fn_abi.ret.layout.is_unit() && !fn_abi.ret.layout.is_never() {
panic!("Kernels should not return anything other than () or !");
}

for arg in &mut fn_abi.args {
if arg.is_ignore() {
continue;
}
classify_arg_kernel(cx, arg);
}
}
32 changes: 32 additions & 0 deletions compiler/rustc_target/src/abi/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1355,6 +1355,10 @@ pub trait TyAbiInterface<'a, C>: Sized {
cx: &C,
offset: Size,
) -> Option<PointeeInfo>;
fn is_adt(this: TyAndLayout<'a, Self>) -> bool;
fn is_never(this: TyAndLayout<'a, Self>) -> bool;
fn is_tuple(this: TyAndLayout<'a, Self>) -> bool;
fn is_unit(this: TyAndLayout<'a, Self>) -> bool;
}

impl<'a, Ty> TyAndLayout<'a, Ty> {
Expand Down Expand Up @@ -1396,6 +1400,34 @@ impl<'a, Ty> TyAndLayout<'a, Ty> {
_ => false,
}
}

pub fn is_adt<C>(self) -> bool
where
Ty: TyAbiInterface<'a, C>,
{
Ty::is_adt(self)
}

pub fn is_never<C>(self) -> bool
where
Ty: TyAbiInterface<'a, C>,
{
Ty::is_never(self)
}

pub fn is_tuple<C>(self) -> bool
where
Ty: TyAbiInterface<'a, C>,
{
Ty::is_tuple(self)
}

pub fn is_unit<C>(self) -> bool
where
Ty: TyAbiInterface<'a, C>,
{
Ty::is_unit(self)
}
}

impl<'a, Ty> TyAndLayout<'a, Ty> {
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_target/src/asm/mips.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ impl MipsInlineAsmRegClass {
}
}

// The reserved registers are somewhat taken from <https://git.io/JUR1k#L150>.
// The reserved registers are somewhat taken from
// <https://github.com/llvm/llvm-project/blob/deb8f8bcf31540c657716ea5242183b0792702a1/llvm/lib/Target/Mips/MipsRegisterInfo.cpp#L150>.
def_regs! {
Mips MipsInlineAsmReg MipsInlineAsmRegClass {
r2: reg = ["$2"],
Expand Down
36 changes: 16 additions & 20 deletions compiler/rustc_typeck/src/check/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2285,14 +2285,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// try to add a suggestion in case the field is a nested field of a field of the Adt
if let Some((fields, substs)) = self.get_field_candidates(span, expr_t) {
for candidate_field in fields.iter() {
if let Some(field_path) = self.check_for_nested_field(
if let Some(mut field_path) = self.check_for_nested_field_satisfying(
span,
field,
&|candidate_field, _| candidate_field.ident(self.tcx()) == field,
candidate_field,
substs,
vec![],
self.tcx.parent_module(id).to_def_id(),
) {
// field_path includes `field` that we're looking for, so pop it.
field_path.pop();

let field_path_str = field_path
.iter()
.map(|id| id.name.to_ident_string())
Expand All @@ -2312,7 +2315,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
err
}

fn get_field_candidates(
crate fn get_field_candidates(
&self,
span: Span,
base_t: Ty<'tcx>,
Expand All @@ -2337,49 +2340,42 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {

/// This method is called after we have encountered a missing field error to recursively
/// search for the field
fn check_for_nested_field(
crate fn check_for_nested_field_satisfying(
&self,
span: Span,
target_field: Ident,
matches: &impl Fn(&ty::FieldDef, Ty<'tcx>) -> bool,
candidate_field: &ty::FieldDef,
subst: SubstsRef<'tcx>,
mut field_path: Vec<Ident>,
id: DefId,
) -> Option<Vec<Ident>> {
debug!(
"check_for_nested_field(span: {:?}, candidate_field: {:?}, field_path: {:?}",
"check_for_nested_field_satisfying(span: {:?}, candidate_field: {:?}, field_path: {:?}",
span, candidate_field, field_path
);

if candidate_field.ident(self.tcx) == target_field {
Some(field_path)
} else if field_path.len() > 3 {
if field_path.len() > 3 {
// For compile-time reasons and to avoid infinite recursion we only check for fields
// up to a depth of three
None
} else {
// recursively search fields of `candidate_field` if it's a ty::Adt

field_path.push(candidate_field.ident(self.tcx).normalize_to_macros_2_0());
let field_ty = candidate_field.ty(self.tcx, subst);
if let Some((nested_fields, subst)) = self.get_field_candidates(span, field_ty) {
for field in nested_fields.iter() {
let accessible = field.vis.is_accessible_from(id, self.tcx);
if accessible {
let ident = field.ident(self.tcx).normalize_to_macros_2_0();
if ident == target_field {
if field.vis.is_accessible_from(id, self.tcx) {
if matches(candidate_field, field_ty) {
return Some(field_path);
}
let field_path = field_path.clone();
if let Some(path) = self.check_for_nested_field(
} else if let Some(field_path) = self.check_for_nested_field_satisfying(
span,
target_field,
matches,
field,
subst,
field_path,
field_path.clone(),
id,
) {
return Some(path);
return Some(field_path);
}
}
}
Expand Down
42 changes: 41 additions & 1 deletion compiler/rustc_typeck/src/check/method/suggest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ use rustc_trait_selection::traits::{
use std::cmp::Ordering;
use std::iter;

use super::probe::Mode;
use super::probe::{Mode, ProbeScope};
use super::{CandidateSource, MethodError, NoMatchData};

impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
Expand Down Expand Up @@ -1129,6 +1129,46 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
label_span_not_found();
}

if let SelfSource::MethodCall(expr) = source
&& let Some((fields, substs)) = self.get_field_candidates(span, actual)
{
let call_expr =
self.tcx.hir().expect_expr(self.tcx.hir().get_parent_node(expr.hir_id));
for candidate_field in fields.iter() {
if let Some(field_path) = self.check_for_nested_field_satisfying(
span,
&|_, field_ty| {
self.lookup_probe(
span,
item_name,
field_ty,
call_expr,
ProbeScope::AllTraits,
)
.is_ok()
},
candidate_field,
substs,
vec![],
self.tcx.parent_module(expr.hir_id).to_def_id(),
) {
let field_path_str = field_path
.iter()
.map(|id| id.name.to_ident_string())
.collect::<Vec<String>>()
.join(".");
debug!("field_path_str: {:?}", field_path_str);

err.span_suggestion_verbose(
item_name.span.shrink_to_lo(),
"one of the expressions' fields has a method of the same name",
format!("{field_path_str}."),
Applicability::MaybeIncorrect,
);
}
}
}

bound_spans.sort();
bound_spans.dedup();
for (span, msg) in bound_spans.into_iter() {
Expand Down
6 changes: 3 additions & 3 deletions library/alloc/src/borrow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -292,8 +292,7 @@ impl<B: ?Sized + ToOwned> Cow<'_, B> {
///
/// # Examples
///
/// Calling `into_owned` on a `Cow::Borrowed` clones the underlying data
/// and becomes a `Cow::Owned`:
/// Calling `into_owned` on a `Cow::Borrowed` returns a clone of the borrowed data:
///
/// ```
/// use std::borrow::Cow;
Expand All @@ -307,7 +306,8 @@ impl<B: ?Sized + ToOwned> Cow<'_, B> {
/// );
/// ```
///
/// Calling `into_owned` on a `Cow::Owned` is a no-op:
/// Calling `into_owned` on a `Cow::Owned` returns the owned data. The data is moved out of the
/// `Cow` without being cloned.
///
/// ```
/// use std::borrow::Cow;
Expand Down
Loading