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 #87399

Closed
wants to merge 16 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -1857,12 +1857,37 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
}
}
GeneratorInteriorOrUpvar::Upvar(upvar_span) => {
// `Some(ref_ty)` if `target_ty` is `&T` and `T` fails to impl `Sync`
let refers_to_non_sync = match target_ty.kind() {
ty::Ref(_, ref_ty, _) => match self.evaluate_obligation(&obligation) {
Ok(eval) if !eval.may_apply() => Some(ref_ty),
_ => None,
},
_ => None,
};

let (span_label, span_note) = match refers_to_non_sync {
// if `target_ty` is `&T` and `T` fails to impl `Sync`,
// include suggestions to make `T: Sync` so that `&T: Send`
Some(ref_ty) => (
format!(
"has type `{}` which {}, because `{}` is not `Sync`",
target_ty, trait_explanation, ref_ty
),
format!(
"captured value {} because `&` references cannot be sent unless their referent is `Sync`",
trait_explanation
),
),
None => (
format!("has type `{}` which {}", target_ty, trait_explanation),
format!("captured value {}", trait_explanation),
),
};

let mut span = MultiSpan::from_span(upvar_span);
span.push_span_label(
upvar_span,
format!("has type `{}` which {}", target_ty, trait_explanation),
);
err.span_note(span, &format!("captured value {}", trait_explanation));
span.push_span_label(upvar_span, span_label);
err.span_note(span, &span_note);
}
}

Expand Down
9 changes: 5 additions & 4 deletions compiler/rustc_typeck/src/check/wfcheck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -523,8 +523,7 @@ fn check_type_defn<'tcx, F>(
fcx.register_wf_obligation(
field.ty.into(),
field.span,
// We don't have an HIR id for the field
ObligationCauseCode::WellFormed(None),
ObligationCauseCode::WellFormed(Some(WellFormedLoc::Ty(field.def_id))),
)
}

Expand Down Expand Up @@ -1467,6 +1466,7 @@ struct AdtVariant<'tcx> {

struct AdtField<'tcx> {
ty: Ty<'tcx>,
def_id: LocalDefId,
span: Span,
}

Expand All @@ -1477,11 +1477,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
.fields()
.iter()
.map(|field| {
let field_ty = self.tcx.type_of(self.tcx.hir().local_def_id(field.hir_id));
let def_id = self.tcx.hir().local_def_id(field.hir_id);
let field_ty = self.tcx.type_of(def_id);
let field_ty = self.normalize_associated_types_in(field.ty.span, field_ty);
let field_ty = self.resolve_vars_if_possible(field_ty);
debug!("non_enum_variant: type of field {:?} is {:?}", field, field_ty);
AdtField { ty: field_ty, span: field.ty.span }
AdtField { ty: field_ty, span: field.ty.span, def_id }
})
.collect();
AdtVariant { fields, explicit_discr: None }
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_typeck/src/hir_wf_check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ fn diagnostic_hir_wf_check<'tcx>(
WellFormedLoc::Ty(def_id) => def_id,
WellFormedLoc::Param { function, param_idx: _ } => function,
};
let hir_id = HirId::make_owner(def_id);
let hir_id = hir.local_def_id_to_hir_id(def_id);

// HIR wfcheck should only ever happen as part of improving an existing error
tcx.sess
Expand Down Expand Up @@ -140,6 +140,7 @@ fn diagnostic_hir_wf_check<'tcx>(
}
ref item => bug!("Unexpected item {:?}", item),
},
hir::Node::Field(field) => Some(field.ty),
ref node => bug!("Unexpected node {:?}", node),
},
WellFormedLoc::Param { function: _, param_idx } => {
Expand Down
9 changes: 5 additions & 4 deletions src/bootstrap/flags.rs
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ Subcommands:
fmt Run rustfmt
test, t Build and run some test suites
bench Build and run some benchmarks
doc Build documentation
doc, d Build documentation
clean Clean out build directories
dist Build distribution artifacts
install Install distribution artifacts
Expand Down Expand Up @@ -244,6 +244,7 @@ To learn more about a subcommand, run `./x.py <subcommand> -h`",
|| (s == "t")
|| (s == "bench")
|| (s == "doc")
|| (s == "d")
|| (s == "clean")
|| (s == "dist")
|| (s == "install")
Expand Down Expand Up @@ -312,7 +313,7 @@ To learn more about a subcommand, run `./x.py <subcommand> -h`",
"clippy" => {
opts.optflag("", "fix", "automatically apply lint suggestions");
}
"doc" => {
"doc" | "d" => {
opts.optflag("", "open", "open the docs in a browser");
}
"clean" => {
Expand Down Expand Up @@ -487,7 +488,7 @@ Arguments:
./x.py test --stage 1",
);
}
"doc" => {
"doc" | "d" => {
subcommand_help.push_str(
"\n
Arguments:
Expand Down Expand Up @@ -573,7 +574,7 @@ Arguments:
},
},
"bench" => Subcommand::Bench { paths, test_args: matches.opt_strs("test-args") },
"doc" => Subcommand::Doc { paths, open: matches.opt_present("open") },
"doc" | "d" => Subcommand::Doc { paths, open: matches.opt_present("open") },
"clean" => {
if !paths.is_empty() {
println!("\nclean does not take a path argument\n");
Expand Down
22 changes: 15 additions & 7 deletions src/librustdoc/doctest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ crate fn run(options: Options) -> Result<(), ErrorReported> {
registry: rustc_driver::diagnostics_registry(),
};

let mut test_args = options.test_args.clone();
let test_args = options.test_args.clone();
let display_warnings = options.display_warnings;
let nocapture = options.nocapture;
let externs = options.externs.clone();
Expand Down Expand Up @@ -166,12 +166,7 @@ crate fn run(options: Options) -> Result<(), ErrorReported> {
Err(ErrorReported) => return Err(ErrorReported),
};

test_args.insert(0, "rustdoctest".to_string());
if nocapture {
test_args.push("--nocapture".to_string());
}

test::test_main(&test_args, tests, Some(test::Options::new().display_output(display_warnings)));
run_tests(test_args, nocapture, display_warnings, tests);

// Collect and warn about unused externs, but only if we've gotten
// reports for each doctest
Expand Down Expand Up @@ -214,6 +209,19 @@ crate fn run(options: Options) -> Result<(), ErrorReported> {
Ok(())
}

crate fn run_tests(
mut test_args: Vec<String>,
nocapture: bool,
display_warnings: bool,
tests: Vec<test::TestDescAndFn>,
) {
test_args.insert(0, "rustdoctest".to_string());
if nocapture {
test_args.push("--nocapture".to_string());
}
test::test_main(&test_args, tests, Some(test::Options::new().display_output(display_warnings)));
}

// Look for `#![doc(test(no_crate_inject))]`, used by crates in the std facade.
fn scrape_test_config(attrs: &[ast::Attribute]) -> TestOptions {
use rustc_ast_pretty::pprust;
Expand Down
5 changes: 1 addition & 4 deletions src/librustdoc/html/render/print_item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1029,14 +1029,12 @@ fn item_enum(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, e: &clean::Enum

use crate::clean::Variant;
if let clean::VariantItem(Variant::Struct(ref s)) = *variant.kind {
let count_fields = s.fields.len();
toggle_open(w, format_args!("{} field{}", count_fields, pluralize(count_fields)));
let variant_id = cx.derive_id(format!(
"{}.{}.fields",
ItemType::Variant,
variant.name.as_ref().unwrap()
));
write!(w, "<div class=\"autohide sub-variant\" id=\"{id}\">", id = variant_id);
write!(w, "<div class=\"sub-variant\" id=\"{id}\">", id = variant_id);
write!(
w,
"<h3>Fields of <b>{name}</b></h3><div>",
Expand Down Expand Up @@ -1064,7 +1062,6 @@ fn item_enum(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, e: &clean::Enum
}
}
w.write_str("</div></div>");
toggle_close(w);
}
}
}
Expand Down
3 changes: 2 additions & 1 deletion src/librustdoc/html/static/css/rustdoc.css
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,7 @@ nav.sub {
.logo-container > img {
max-width: 100px;
max-height: 100px;
height: 100%;
position: absolute;
left: 50%;
top: 50%;
Expand Down Expand Up @@ -1072,7 +1073,7 @@ a.test-arrow:hover{
padding-top: 1px;
}

#main > details > .sub-variant > h3 {
#main .sub-variant > h3 {
font-size: 15px;
margin-left: 25px;
margin-bottom: 5px;
Expand Down
13 changes: 5 additions & 8 deletions src/librustdoc/markdown.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ crate fn render<P: AsRef<Path>>(
}

/// Runs any tests/code examples in the markdown file `input`.
crate fn test(mut options: Options) -> Result<(), String> {
crate fn test(options: Options) -> Result<(), String> {
let input_str = read_to_string(&options.input)
.map_err(|err| format!("{}: {}", options.input.display(), err))?;
let mut opts = TestOptions::default();
Expand All @@ -135,14 +135,11 @@ crate fn test(mut options: Options) -> Result<(), String> {

find_testable_code(&input_str, &mut collector, codes, options.enable_per_target_ignores, None);

options.test_args.insert(0, "rustdoctest".to_string());
if options.nocapture {
options.test_args.push("--nocapture".to_string());
}
test::test_main(
&options.test_args,
crate::doctest::run_tests(
options.test_args,
options.nocapture,
options.display_warnings,
collector.tests,
Some(test::Options::new().display_output(options.display_warnings)),
);
Ok(())
}
6 changes: 2 additions & 4 deletions src/test/rustdoc/toggle-item-contents.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,7 @@ pub struct PrivStruct {
}

// @has 'toggle_item_contents/enum.Enum.html'
// @count - '//details[@class="rustdoc-toggle type-contents-toggle"]' 1
// @has - '//details[@class="rustdoc-toggle type-contents-toggle"]' 'Show 2 fields'
// @!has - '//details[@class="rustdoc-toggle type-contents-toggle"]'
pub enum Enum {
A, B, C,
D {
Expand All @@ -73,8 +72,7 @@ pub enum Enum {
}

// @has 'toggle_item_contents/enum.EnumStructVariant.html'
// @count - '//details[@class="rustdoc-toggle type-contents-toggle"]' 1
// @has - '//details[@class="rustdoc-toggle type-contents-toggle"]' 'Show 1 field'
// @!has - '//details[@class="rustdoc-toggle type-contents-toggle"]'
pub enum EnumStructVariant {
A, B, C,
D {
Expand Down
25 changes: 25 additions & 0 deletions src/test/ui/async-await/issue-86507.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// edition:2018

use ::core::pin::Pin;
use ::core::future::Future;
use ::core::marker::Send;

trait Foo {
fn bar<'me, 'async_trait, T: Send>(x: &'me T)
-> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>
where 'me: 'async_trait;
}

impl Foo for () {
fn bar<'me, 'async_trait, T: Send>(x: &'me T)
-> Pin<Box<dyn Future<Output = ()> + Send + 'async_trait>>
where 'me:'async_trait {
Box::pin( //~ ERROR future cannot be sent between threads safely
async move {
let x = x;
}
)
}
}

fn main() { }
23 changes: 23 additions & 0 deletions src/test/ui/async-await/issue-86507.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
error: future cannot be sent between threads safely
--> $DIR/issue-86507.rs:17:13
|
LL | / Box::pin(
LL | | async move {
LL | | let x = x;
LL | | }
LL | | )
| |_____________^ future created by async block is not `Send`
|
note: captured value is not `Send` because `&` references cannot be sent unless their referent is `Sync`
--> $DIR/issue-86507.rs:19:29
|
LL | let x = x;
| ^ has type `&T` which is not `Send`, because `T` is not `Sync`
= note: required for the cast to the object type `dyn Future<Output = ()> + Send`
help: consider further restricting type parameter `T`
|
LL | where 'me:'async_trait, T: std::marker::Sync {
| ^^^^^^^^^^^^^^^^^^^^^^

error: aborting due to previous error

3 changes: 3 additions & 0 deletions src/test/ui/bastion-of-the-turbofish.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,12 @@
//
// My heart aches in sorrow, for I know I am defeated. Let this be a warning
// to all those who come after. Here stands the bastion of the Turbofish.
//
// RIP Anna Harren, Guardian Angel of the Hallowed Turbofish. <3

// See https://github.com/rust-lang/rust/pull/53562
// and https://github.com/rust-lang/rfcs/pull/2527
// and https://twitter.com/garblefart/status/1393236602856611843
// for context.

fn main() {
Expand Down
7 changes: 7 additions & 0 deletions src/test/ui/impl-trait/issues/issue-54600.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
use std::fmt::Debug;

fn main() {
let x: Option<impl Debug> = Some(44_u32);
//~^ `impl Trait` not allowed outside of function and method return types
println!("{:?}", x);
}
9 changes: 9 additions & 0 deletions src/test/ui/impl-trait/issues/issue-54600.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
error[E0562]: `impl Trait` not allowed outside of function and method return types
--> $DIR/issue-54600.rs:4:19
|
LL | let x: Option<impl Debug> = Some(44_u32);
| ^^^^^^^^^^

error: aborting due to previous error

For more information about this error, try `rustc --explain E0562`.
7 changes: 7 additions & 0 deletions src/test/ui/impl-trait/issues/issue-54840.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
use std::ops::Add;

fn main() {
let i: i32 = 0;
let j: &impl Add = &i;
//~^ `impl Trait` not allowed outside of function and method return types
}
9 changes: 9 additions & 0 deletions src/test/ui/impl-trait/issues/issue-54840.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
error[E0562]: `impl Trait` not allowed outside of function and method return types
--> $DIR/issue-54840.rs:5:13
|
LL | let j: &impl Add = &i;
| ^^^^^^^^

error: aborting due to previous error

For more information about this error, try `rustc --explain E0562`.
12 changes: 12 additions & 0 deletions src/test/ui/impl-trait/issues/issue-58504.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#![feature(generators, generator_trait, never_type)]

use std::ops::Generator;

fn mk_gen() -> impl Generator<Return=!, Yield=()> {
|| { loop { yield; } }
}

fn main() {
let gens: [impl Generator<Return=!, Yield=()>;2] = [ mk_gen(), mk_gen() ];
//~^ `impl Trait` not allowed outside of function and method return types
}
9 changes: 9 additions & 0 deletions src/test/ui/impl-trait/issues/issue-58504.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
error[E0562]: `impl Trait` not allowed outside of function and method return types
--> $DIR/issue-58504.rs:10:16
|
LL | let gens: [impl Generator<Return=!, Yield=()>;2] = [ mk_gen(), mk_gen() ];
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error: aborting due to previous error

For more information about this error, try `rustc --explain E0562`.
Loading