1
Fork 0

Auto merge of #102995 - JohnTitor:rollup-yomkwge, r=JohnTitor

Rollup of 7 pull requests

Successful merges:

 - #102641 (Support casting boxes to dyn*)
 - #102836 (rustc_target: Fix json target specs using LLD linker flavors in link args)
 - #102949 (should-skip-this: add missing backslash)
 - #102967 (Add test for issue 102964)
 - #102971 (tidy: error if a lang feature is already present)
 - #102974 (Fix small word dupe typos)
 - #102980 (rustdoc: merge separate `.item-info` CSS)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2022-10-13 03:33:40 +00:00
commit 3cf5fc58d5
25 changed files with 229 additions and 162 deletions

View file

@ -14,6 +14,7 @@ use rustc_middle::ty::cast::{CastTy, IntTy};
use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf};
use rustc_middle::ty::{self, adjustment::PointerCast, Instance, Ty, TyCtxt};
use rustc_span::source_map::{Span, DUMMY_SP};
use rustc_target::abi::Size;
impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
#[instrument(level = "trace", skip(self, bx))]
@ -285,6 +286,14 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
bug!("Only valid to do a DynStar cast into a DynStar type")
};
let vtable = get_vtable(bx.cx(), source.ty(self.mir, bx.tcx()), trait_ref);
let vtable = bx.pointercast(vtable, bx.cx().type_ptr_to(bx.cx().type_isize()));
// FIXME(dyn-star): this is probably not the best way to check if this is
// a pointer, and really we should ensure that the value is a suitable
// pointer earlier in the compilation process.
let data = match operand.layout.pointee_info_at(bx.cx(), Size::ZERO) {
Some(_) => bx.ptrtoint(data, bx.cx().type_isize()),
None => data,
};
OperandValue::Pair(data, vtable)
}
mir::CastKind::Pointer(

View file

@ -53,8 +53,8 @@ unsafe {
```
Here, transmute is being used to convert the types of the fn arguments.
This pattern is incorrect because, because the type of `foo` is a function
**item** (`typeof(foo)`), which is zero-sized, and the target type (`fn()`)
This pattern is incorrect because the type of `foo` is a function **item**
(`typeof(foo)`), which is zero-sized, and the target type (`fn()`)
is a function pointer, which is not zero-sized.
This pattern should be rewritten. There are a few possible ways to do this:

View file

@ -1283,7 +1283,7 @@ impl<'tcx> InferCtxt<'tcx> {
assert!(old_value.is_none());
}
/// Process the region constraints and return any any errors that
/// Process the region constraints and return any errors that
/// result. After this, no more unification operations should be
/// done -- or the compiler will panic -- but it is legal to use
/// `resolve_vars_if_possible` as well as `fully_resolve`.

View file

@ -1739,11 +1739,15 @@ impl TargetOptions {
self.lld_flavor_json,
self.linker_is_gnu_json,
);
match linker_flavor {
LinkerFlavor::Gnu(_, Lld::Yes)
| LinkerFlavor::Darwin(_, Lld::Yes)
| LinkerFlavor::Msvc(Lld::Yes) => {}
_ => add_link_args_iter(args, linker_flavor, args_json.iter().cloned()),
// Normalize to no lld to avoid asserts.
let linker_flavor = match linker_flavor {
LinkerFlavor::Gnu(cc, _) => LinkerFlavor::Gnu(cc, Lld::No),
LinkerFlavor::Darwin(cc, _) => LinkerFlavor::Darwin(cc, Lld::No),
LinkerFlavor::Msvc(_) => LinkerFlavor::Msvc(Lld::No),
_ => linker_flavor,
};
if !args.contains_key(&linker_flavor) {
add_link_args_iter(args, linker_flavor, args_json.iter().cloned());
}
}
}

View file

@ -86,7 +86,7 @@ fn test_errorkind_packing() {
assert_eq!(Error::from(ErrorKind::NotFound).kind(), ErrorKind::NotFound);
assert_eq!(Error::from(ErrorKind::PermissionDenied).kind(), ErrorKind::PermissionDenied);
assert_eq!(Error::from(ErrorKind::Uncategorized).kind(), ErrorKind::Uncategorized);
// Check that the innards look like like what we want.
// Check that the innards look like what we want.
assert_matches!(
Error::from(ErrorKind::OutOfMemory).repr.data(),
ErrorData::Simple(ErrorKind::OutOfMemory),

View file

@ -20,7 +20,7 @@
//! Since those syscalls have requirements that cannot be fully checked in advance and
//! gathering additional information about file descriptors would require additional syscalls
//! anyway it simply attempts to use them one after another (guided by inaccurate hints) to
//! figure out which one works and and falls back to the generic read-write copy loop if none of them
//! figure out which one works and falls back to the generic read-write copy loop if none of them
//! does.
//! Once a working syscall is found for a pair of file descriptors it will be called in a loop
//! until the copy operation is completed.

View file

@ -19,7 +19,7 @@ if [[ -n "${CI_ONLY_WHEN_SUBMODULES_CHANGED-}" ]]; then
# those files are present in the diff a submodule was updated.
echo "Submodules were updated"
elif ! (git diff --quiet "$BASE_COMMIT" -- \
src/tools/clippy src/tools/rustfmt src/tools/miri
src/tools/clippy src/tools/rustfmt src/tools/miri \
library/std/src/sys); then
# There is not an easy blanket search for subtrees. For now, manually list
# the subtrees.

View file

@ -692,16 +692,13 @@ pre, .rustdoc.source .example-wrap {
.item-info {
display: block;
}
.content .item-info code {
font-size: 0.875rem;
}
.content .item-info {
margin-left: 24px;
}
.item-info code {
font-size: 0.875rem;
}
#main-content > .item-info {
margin-top: 0;
margin-left: 0;
@ -1945,7 +1942,7 @@ in storage.js plus the media query with (min-width: 701px)
}
/* Align summary-nested and unnested item-info gizmos. */
.content .impl-items > .item-info {
.impl-items > .item-info {
margin-left: 34px;
}
}

View file

@ -1,7 +1,7 @@
#![feature(negative_impls)]
// edition:2018
// This tests the the specialized async-await-specific error when futures don't implement an
// This tests the specialized async-await-specific error when futures don't implement an
// auto trait (which is specifically Sync) due to some type that was captured.
struct Foo;

View file

@ -1,7 +1,7 @@
#![feature(negative_impls)]
// edition:2018
// This tests the the specialized async-await-specific error when futures don't implement an
// This tests the specialized async-await-specific error when futures don't implement an
// auto trait (which is specifically Send) due to some type that was captured.
struct Foo;

View file

@ -2,7 +2,7 @@
#![feature(negative_impls)]
// edition:2018
// This tests the the unspecialized async-await-specific error when futures don't implement an
// This tests the unspecialized async-await-specific error when futures don't implement an
// auto trait (which is not Send or Sync) due to some type that was captured.
auto trait Qux {}

View file

@ -1,7 +1,7 @@
#![feature(generic_const_exprs)]
#![allow(incomplete_features)]
// The goal is is to get an unevaluated const `ct` with a `Ty::Infer(TyVar(_#1t)` subst.
// The goal is to get an unevaluated const `ct` with a `Ty::Infer(TyVar(_#1t)` subst.
//
// If we are then able to infer `ty::Infer(TyVar(_#1t) := Ty<ct>` we introduced an
// artificial inference cycle.

View file

@ -1,7 +1,7 @@
#![feature(generic_const_exprs)]
#![allow(incomplete_features)]
// The goal is is to get an unevaluated const `ct` with a `Ty::Infer(TyVar(_#1t)` subst.
// The goal is to get an unevaluated const `ct` with a `Ty::Infer(TyVar(_#1t)` subst.
//
// If we are then able to infer `ty::Infer(TyVar(_#1t) := Ty<ct>` we introduced an
// artificial inference cycle.

View file

@ -51,7 +51,7 @@ mod cross_crate {
let _ = nested::DeprecatedTupleStruct (1); //~ ERROR use of deprecated tuple struct `deprecation_lint::nested::DeprecatedTupleStruct`: text
// At the moment, the lint checker only checks stability in
// At the moment, the lint checker only checks stability
// in the arguments of macros.
// Eventually, we will want to lint the contents of the
// macro in the module *defining* it. Also, stability levels

View file

@ -0,0 +1,17 @@
// run-pass
// compile-flags: -C opt-level=0
#![feature(dyn_star)]
#![allow(incomplete_features)]
use std::fmt::Display;
fn make_dyn_star() -> dyn* Display {
Box::new(42) as dyn* Display
}
fn main() {
let x = make_dyn_star();
println!("{x}");
}

View file

@ -47,8 +47,8 @@ unsafe {
```
Here, transmute is being used to convert the types of the fn arguments.
This pattern is incorrect because, because the type of `foo` is a function
**item** (`typeof(foo)`), which is zero-sized, and the target type (`fn()`)
This pattern is incorrect because the type of `foo` is a function **item**
(`typeof(foo)`), which is zero-sized, and the target type (`fn()`)
is a function pointer, which is not zero-sized.
This pattern should be rewritten. There are a few possible ways to do this:

View file

@ -0,0 +1,10 @@
use std::rc::Rc;
type Foo<'a, T> = &'a dyn Fn(&T);
type RcFoo<'a, T> = Rc<Foo<'a, T>>;
fn bar_function<T>(function: Foo<T>) -> RcFoo<T> {
//~^ ERROR mismatched types
let rc = Rc::new(function);
}
fn main() {}

View file

@ -0,0 +1,19 @@
error[E0308]: mismatched types
--> $DIR/issue-102964.rs:5:41
|
LL | fn bar_function<T>(function: Foo<T>) -> RcFoo<T> {
| ------------ ^^^^^^^^ expected struct `Rc`, found `()`
| |
| implicitly returns `()` as its body has no tail or `return` expression
|
= note: expected struct `Rc<&dyn for<'a> Fn(&'a T)>`
found unit type `()`
help: consider returning the local binding `rc`
|
LL ~ let rc = Rc::new(function);
LL + rc
|
error: aborting due to previous error
For more information about this error, try `rustc --explain E0308`.

View file

@ -7,7 +7,7 @@ macro_rules! zip {
zip!([$($rest),*], $a.zip($b), (x,y), [x,y])
};
// Intermediate steps to build the zipped expression, the match pattern, and
// Intermediate steps to build the zipped expression, the match pattern
// and the output tuple of the closure, using macro hygiene to repeatedly
// introduce new variables named 'x'.
([$a:expr, $($rest:expr),*], $zip:expr, $pat:pat, [$($flat:expr),*]) => {

View file

@ -1,4 +1,4 @@
// Test for for diagnostic improvement issue #75907
// Test for diagnostic improvement issue #75907
mod foo {
pub(crate) struct Foo(u8);

View file

@ -1,4 +1,4 @@
// Test for for diagnostic improvement issue #75907, extern crate
// Test for diagnostic improvement issue #75907, extern crate
// aux-build:issue-75907.rs
extern crate issue_75907 as a;

View file

@ -130,7 +130,7 @@ mod cross_crate {
let _ = UnstableTupleStruct (1);
let _ = StableTupleStruct (1);
// At the moment, the lint checker only checks stability in
// At the moment, the lint checker only checks stability
// in the arguments of macros.
// Eventually, we will want to lint the contents of the
// macro in the module *defining* it. Also, stability levels

View file

@ -19,8 +19,8 @@ macro_rules! produce_it {
// `print_def_site!` will respan the `$crate` identifier
// with `Span::def_site()`. This should cause it to resolve
// relative to `meta_macro`, *not* `make_macro` (despite
// the fact that that `print_def_site` is produced by
// a `macro_rules!` macro in `make_macro`).
// the fact that `print_def_site` is produced by a
// `macro_rules!` macro in `make_macro`).
meta_macro::print_def_site!($crate::dummy!());
}
}

View file

@ -35,8 +35,8 @@ macro_rules! produce_it
// `print_def_site!` will respan the `$crate` identifier
// with `Span::def_site()`. This should cause it to resolve
// relative to `meta_macro`, *not* `make_macro` (despite
// the fact that that `print_def_site` is produced by
// a `macro_rules!` macro in `make_macro`).
// the fact that `print_def_site` is produced by a
// `macro_rules!` macro in `make_macro`).
}
}

View file

@ -10,7 +10,7 @@
//! * Language features in a group are sorted by feature name.
use crate::walk::{filter_dirs, walk, walk_many};
use std::collections::HashMap;
use std::collections::hash_map::{Entry, HashMap};
use std::fmt;
use std::fs;
use std::num::NonZeroU32;
@ -280,13 +280,14 @@ fn test_filen_gate(filen_underscore: &str, features: &mut Features) -> bool {
}
pub fn collect_lang_features(base_compiler_path: &Path, bad: &mut bool) -> Features {
let mut all = collect_lang_features_in(base_compiler_path, "active.rs", bad);
all.extend(collect_lang_features_in(base_compiler_path, "accepted.rs", bad));
all.extend(collect_lang_features_in(base_compiler_path, "removed.rs", bad));
all
let mut features = Features::new();
collect_lang_features_in(&mut features, base_compiler_path, "active.rs", bad);
collect_lang_features_in(&mut features, base_compiler_path, "accepted.rs", bad);
collect_lang_features_in(&mut features, base_compiler_path, "removed.rs", bad);
features
}
fn collect_lang_features_in(base: &Path, file: &str, bad: &mut bool) -> Features {
fn collect_lang_features_in(features: &mut Features, base: &Path, file: &str, bad: &mut bool) {
let path = base.join("rustc_feature").join("src").join(file);
let contents = t!(fs::read_to_string(&path));
@ -298,135 +299,145 @@ fn collect_lang_features_in(base: &Path, file: &str, bad: &mut bool) -> Features
let mut in_feature_group = false;
let mut prev_names = vec![];
contents
.lines()
.zip(1..)
.filter_map(|(line, line_number)| {
let line = line.trim();
let lines = contents.lines().zip(1..);
for (line, line_number) in lines {
let line = line.trim();
// Within -start and -end, the tracking issue can be omitted.
match line {
"// no-tracking-issue-start" => {
next_feature_omits_tracking_issue = true;
return None;
}
"// no-tracking-issue-end" => {
next_feature_omits_tracking_issue = false;
return None;
}
_ => {}
// Within -start and -end, the tracking issue can be omitted.
match line {
"// no-tracking-issue-start" => {
next_feature_omits_tracking_issue = true;
continue;
}
if line.starts_with(FEATURE_GROUP_START_PREFIX) {
if in_feature_group {
tidy_error!(
bad,
"{}:{}: \
new feature group is started without ending the previous one",
path.display(),
line_number,
);
}
in_feature_group = true;
prev_names = vec![];
return None;
} else if line.starts_with(FEATURE_GROUP_END_PREFIX) {
in_feature_group = false;
prev_names = vec![];
return None;
"// no-tracking-issue-end" => {
next_feature_omits_tracking_issue = false;
continue;
}
_ => {}
}
let mut parts = line.split(',');
let level = match parts.next().map(|l| l.trim().trim_start_matches('(')) {
Some("active") => Status::Unstable,
Some("incomplete") => Status::Unstable,
Some("removed") => Status::Removed,
Some("accepted") => Status::Stable,
_ => return None,
};
let name = parts.next().unwrap().trim();
let since_str = parts.next().unwrap().trim().trim_matches('"');
let since = match since_str.parse() {
Ok(since) => Some(since),
Err(err) => {
tidy_error!(
bad,
"{}:{}: failed to parse since: {} ({:?})",
path.display(),
line_number,
since_str,
err,
);
None
}
};
if line.starts_with(FEATURE_GROUP_START_PREFIX) {
if in_feature_group {
if prev_names.last() > Some(&name) {
// This assumes the user adds the feature name at the end of the list, as we're
// not looking ahead.
let correct_index = match prev_names.binary_search(&name) {
Ok(_) => {
// This only occurs when the feature name has already been declared.
tidy_error!(
bad,
"{}:{}: duplicate feature {}",
path.display(),
line_number,
name,
);
// skip any additional checks for this line
return None;
}
Err(index) => index,
};
let correct_placement = if correct_index == 0 {
"at the beginning of the feature group".to_owned()
} else if correct_index == prev_names.len() {
// I don't believe this is reachable given the above assumption, but it
// doesn't hurt to be safe.
"at the end of the feature group".to_owned()
} else {
format!(
"between {} and {}",
prev_names[correct_index - 1],
prev_names[correct_index],
)
};
tidy_error!(
bad,
"{}:{}: feature {} is not sorted by feature name (should be {})",
path.display(),
line_number,
name,
correct_placement,
);
}
prev_names.push(name);
tidy_error!(
bad,
"{}:{}: \
new feature group is started without ending the previous one",
path.display(),
line_number,
);
}
let issue_str = parts.next().unwrap().trim();
let tracking_issue = if issue_str.starts_with("None") {
if level == Status::Unstable && !next_feature_omits_tracking_issue {
tidy_error!(
bad,
"{}:{}: no tracking issue for feature {}",
path.display(),
line_number,
name,
);
}
in_feature_group = true;
prev_names = vec![];
continue;
} else if line.starts_with(FEATURE_GROUP_END_PREFIX) {
in_feature_group = false;
prev_names = vec![];
continue;
}
let mut parts = line.split(',');
let level = match parts.next().map(|l| l.trim().trim_start_matches('(')) {
Some("active") => Status::Unstable,
Some("incomplete") => Status::Unstable,
Some("removed") => Status::Removed,
Some("accepted") => Status::Stable,
_ => continue,
};
let name = parts.next().unwrap().trim();
let since_str = parts.next().unwrap().trim().trim_matches('"');
let since = match since_str.parse() {
Ok(since) => Some(since),
Err(err) => {
tidy_error!(
bad,
"{}:{}: failed to parse since: {} ({:?})",
path.display(),
line_number,
since_str,
err,
);
None
} else {
let s = issue_str.split('(').nth(1).unwrap().split(')').next().unwrap();
Some(s.parse().unwrap())
};
Some((name.to_owned(), Feature { level, since, has_gate_test: false, tracking_issue }))
})
.collect()
}
};
if in_feature_group {
if prev_names.last() > Some(&name) {
// This assumes the user adds the feature name at the end of the list, as we're
// not looking ahead.
let correct_index = match prev_names.binary_search(&name) {
Ok(_) => {
// This only occurs when the feature name has already been declared.
tidy_error!(
bad,
"{}:{}: duplicate feature {}",
path.display(),
line_number,
name,
);
// skip any additional checks for this line
continue;
}
Err(index) => index,
};
let correct_placement = if correct_index == 0 {
"at the beginning of the feature group".to_owned()
} else if correct_index == prev_names.len() {
// I don't believe this is reachable given the above assumption, but it
// doesn't hurt to be safe.
"at the end of the feature group".to_owned()
} else {
format!(
"between {} and {}",
prev_names[correct_index - 1],
prev_names[correct_index],
)
};
tidy_error!(
bad,
"{}:{}: feature {} is not sorted by feature name (should be {})",
path.display(),
line_number,
name,
correct_placement,
);
}
prev_names.push(name);
}
let issue_str = parts.next().unwrap().trim();
let tracking_issue = if issue_str.starts_with("None") {
if level == Status::Unstable && !next_feature_omits_tracking_issue {
tidy_error!(
bad,
"{}:{}: no tracking issue for feature {}",
path.display(),
line_number,
name,
);
}
None
} else {
let s = issue_str.split('(').nth(1).unwrap().split(')').next().unwrap();
Some(s.parse().unwrap())
};
match features.entry(name.to_owned()) {
Entry::Occupied(e) => {
tidy_error!(
bad,
"{}:{} feature {name} already specified with status '{}'",
path.display(),
line_number,
e.get().level,
);
}
Entry::Vacant(e) => {
e.insert(Feature { level, since, has_gate_test: false, tracking_issue });
}
}
}
}
fn get_and_check_lib_features(