Skip to content

Commit

Permalink
Auto merge of rust-lang#102165 - matthiaskrgr:rollup-n5oquhe, r=matth…
Browse files Browse the repository at this point in the history
…iaskrgr

Rollup of 8 pull requests

Successful merges:

 - rust-lang#100734 (Split out async_fn_in_trait into a separate feature)
 - rust-lang#101664 (Note if mismatched types have a similar name)
 - rust-lang#101815 (Migrated the rustc_passes annotation without effect diagnostic infrastructure)
 - rust-lang#102042 (Distribute rust-docs-json via rustup.)
 - rust-lang#102066 (rustdoc: remove unnecessary `max-width` on headers)
 - rust-lang#102095 (Deduplicate two functions that would soon have been three)
 - rust-lang#102104 (Set 'exec-env:RUST_BACKTRACE=0' in const-eval-select tests)
 - rust-lang#102112 (Allow full relro on powerpc64-unknown-linux-gnu)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
  • Loading branch information
bors committed Sep 23, 2022
2 parents bc4d574 + 8e3b9bc commit 4d44e09
Show file tree
Hide file tree
Showing 37 changed files with 442 additions and 72 deletions.
23 changes: 18 additions & 5 deletions compiler/rustc_ast_lowering/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,15 @@ impl FnDeclKind {
_ => false,
}
}

fn async_fn_allowed(&self, tcx: TyCtxt<'_>) -> bool {
match self {
FnDeclKind::Fn | FnDeclKind::Inherent => true,
FnDeclKind::Impl if tcx.features().async_fn_in_trait => true,
FnDeclKind::Trait if tcx.features().async_fn_in_trait => true,
_ => false,
}
}
}

#[derive(Copy, Clone)]
Expand Down Expand Up @@ -1692,14 +1701,14 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
}));

let output = if let Some((ret_id, span)) = make_ret_async {
if !kind.impl_trait_allowed(self.tcx) {
if !kind.async_fn_allowed(self.tcx) {
match kind {
FnDeclKind::Trait | FnDeclKind::Impl => {
self.tcx
.sess
.create_feature_err(
TraitFnAsync { fn_span, span },
sym::return_position_impl_trait_in_trait,
sym::async_fn_in_trait,
)
.emit();
}
Expand Down Expand Up @@ -1917,9 +1926,13 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
let future_bound = this.lower_async_fn_output_type_to_future_bound(
output,
span,
ImplTraitContext::ReturnPositionOpaqueTy {
origin: hir::OpaqueTyOrigin::FnReturn(fn_def_id),
in_trait,
if in_trait && !this.tcx.features().return_position_impl_trait_in_trait {
ImplTraitContext::Disallowed(ImplTraitPosition::TraitReturn)
} else {
ImplTraitContext::ReturnPositionOpaqueTy {
origin: hir::OpaqueTyOrigin::FnReturn(fn_def_id),
in_trait,
}
},
);

Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_error_messages/locales/en-US/passes.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -268,3 +268,6 @@ passes_link_ordinal = attribute should be applied to a foreign function or stati
passes_collapse_debuginfo = `collapse_debuginfo` attribute should be applied to macro definitions
.label = not a macro definition
passes_deprecated_annotation_has_no_effect = this `#[deprecated]` annotation has no effect
.suggestion = remove the unnecessary deprecation attribute
2 changes: 2 additions & 0 deletions compiler/rustc_feature/src/active.rs
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,8 @@ declare_features! (
(active, associated_type_defaults, "1.2.0", Some(29661), None),
/// Allows `async || body` closures.
(active, async_closure, "1.37.0", Some(62290), None),
/// Alows async functions to be declared, implemented, and used in traits.
(incomplete, async_fn_in_trait, "CURRENT_RUSTC_VERSION", Some(91611), None),
/// Allows `extern "C-unwind" fn` to enable unwinding across ABI boundaries.
(active, c_unwind, "1.52.0", Some(74990), None),
/// Allows using C-variadics.
Expand Down
115 changes: 111 additions & 4 deletions compiler/rustc_infer/src/infer/error_reporting/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ use super::{InferCtxt, RegionVariableOrigin, SubregionOrigin, TypeTrace, ValuePa

use crate::infer;
use crate::infer::error_reporting::nice_region_error::find_anon_type::find_anon_type;
use crate::infer::ExpectedFound;
use crate::traits::error_reporting::report_object_safety_error;
use crate::traits::{
IfExpressionCause, MatchExpressionArmCause, ObligationCause, ObligationCauseCode,
Expand Down Expand Up @@ -1653,8 +1654,114 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
),
Mismatch::Fixed(s) => (s.into(), s.into(), None),
};
match (&terr, expected == found) {
(TypeError::Sorts(values), extra) => {

enum Similar<'tcx> {
Adts { expected: ty::AdtDef<'tcx>, found: ty::AdtDef<'tcx> },
PrimitiveFound { expected: ty::AdtDef<'tcx>, found: Ty<'tcx> },
PrimitiveExpected { expected: Ty<'tcx>, found: ty::AdtDef<'tcx> },
}

let similarity = |ExpectedFound { expected, found }: ExpectedFound<Ty<'tcx>>| {
if let ty::Adt(expected, _) = expected.kind() && let Some(primitive) = found.primitive_symbol() {
let path = self.tcx.def_path(expected.did()).data;
let name = path.last().unwrap().data.get_opt_name();
if name == Some(primitive) {
return Some(Similar::PrimitiveFound { expected: *expected, found });
}
} else if let Some(primitive) = expected.primitive_symbol() && let ty::Adt(found, _) = found.kind() {
let path = self.tcx.def_path(found.did()).data;
let name = path.last().unwrap().data.get_opt_name();
if name == Some(primitive) {
return Some(Similar::PrimitiveExpected { expected, found: *found });
}
} else if let ty::Adt(expected, _) = expected.kind() && let ty::Adt(found, _) = found.kind() {
if !expected.did().is_local() && expected.did().krate == found.did().krate {
// Most likely types from different versions of the same crate
// are in play, in which case this message isn't so helpful.
// A "perhaps two different versions..." error is already emitted for that.
return None;
}
let f_path = self.tcx.def_path(found.did()).data;
let e_path = self.tcx.def_path(expected.did()).data;

if let (Some(e_last), Some(f_last)) = (e_path.last(), f_path.last()) && e_last == f_last {
return Some(Similar::Adts{expected: *expected, found: *found});
}
}
None
};

match terr {
// If two types mismatch but have similar names, mention that specifically.
TypeError::Sorts(values) if let Some(s) = similarity(values) => {
let diagnose_primitive =
|prim: Ty<'tcx>,
shadow: Ty<'tcx>,
defid: DefId,
diagnostic: &mut Diagnostic| {
let name = shadow.sort_string(self.tcx);
diagnostic.note(format!(
"{prim} and {name} have similar names, but are actually distinct types"
));
diagnostic
.note(format!("{prim} is a primitive defined by the language"));
let def_span = self.tcx.def_span(defid);
let msg = if defid.is_local() {
format!("{name} is defined in the current crate")
} else {
let crate_name = self.tcx.crate_name(defid.krate);
format!("{name} is defined in crate `{crate_name}")
};
diagnostic.span_note(def_span, msg);
};

let diagnose_adts =
|expected_adt : ty::AdtDef<'tcx>,
found_adt: ty::AdtDef<'tcx>,
diagnostic: &mut Diagnostic| {
let found_name = values.found.sort_string(self.tcx);
let expected_name = values.expected.sort_string(self.tcx);

let found_defid = found_adt.did();
let expected_defid = expected_adt.did();

diagnostic.note(format!("{found_name} and {expected_name} have similar names, but are actually distinct types"));
for (defid, name) in
[(found_defid, found_name), (expected_defid, expected_name)]
{
let def_span = self.tcx.def_span(defid);

let msg = if found_defid.is_local() && expected_defid.is_local() {
let module = self
.tcx
.parent_module_from_def_id(defid.expect_local())
.to_def_id();
let module_name = self.tcx.def_path(module).to_string_no_crate_verbose();
format!("{name} is defined in module `crate{module_name}` of the current crate")
} else if defid.is_local() {
format!("{name} is defined in the current crate")
} else {
let crate_name = self.tcx.crate_name(defid.krate);
format!("{name} is defined in crate `{crate_name}`")
};
diagnostic.span_note(def_span, msg);
}
};

match s {
Similar::Adts{expected, found} => {
diagnose_adts(expected, found, diag)
}
Similar::PrimitiveFound{expected, found: prim} => {
diagnose_primitive(prim, values.expected, expected.did(), diag)
}
Similar::PrimitiveExpected{expected: prim, found} => {
diagnose_primitive(prim, values.found, found.did(), diag)
}
}
}
TypeError::Sorts(values) => {
let extra = expected == found;
let sort_string = |ty: Ty<'tcx>| match (extra, ty.kind()) {
(true, ty::Opaque(def_id, _)) => {
let sm = self.tcx.sess.source_map();
Expand Down Expand Up @@ -1707,10 +1814,10 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
);
}
}
(TypeError::ObjectUnsafeCoercion(_), _) => {
TypeError::ObjectUnsafeCoercion(_) => {
diag.note_unsuccessful_coercion(found, expected);
}
(_, _) => {
_ => {
debug!(
"note_type_err: exp_found={:?}, expected={:?} found={:?}",
exp_found, expected, found
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_infer/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#![cfg_attr(bootstrap, feature(label_break_value))]
#![feature(let_chains)]
#![cfg_attr(bootstrap, feature(let_else))]
#![feature(if_let_guard)]
#![feature(min_specialization)]
#![feature(never_type)]
#![feature(try_blocks)]
Expand Down
31 changes: 30 additions & 1 deletion compiler/rustc_middle/src/ty/sty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ use rustc_hir as hir;
use rustc_hir::def_id::DefId;
use rustc_index::vec::Idx;
use rustc_macros::HashStable;
use rustc_span::symbol::{kw, Symbol};
use rustc_span::symbol::{kw, sym, Symbol};
use rustc_target::abi::VariantIdx;
use rustc_target::spec::abi;
use std::borrow::Cow;
Expand Down Expand Up @@ -2207,6 +2207,35 @@ impl<'tcx> Ty<'tcx> {
}
}
}

// If `self` is a primitive, return its [`Symbol`].
pub fn primitive_symbol(self) -> Option<Symbol> {
match self.kind() {
ty::Bool => Some(sym::bool),
ty::Char => Some(sym::char),
ty::Float(f) => match f {
ty::FloatTy::F32 => Some(sym::f32),
ty::FloatTy::F64 => Some(sym::f64),
},
ty::Int(f) => match f {
ty::IntTy::Isize => Some(sym::isize),
ty::IntTy::I8 => Some(sym::i8),
ty::IntTy::I16 => Some(sym::i16),
ty::IntTy::I32 => Some(sym::i32),
ty::IntTy::I64 => Some(sym::i64),
ty::IntTy::I128 => Some(sym::i128),
},
ty::Uint(f) => match f {
ty::UintTy::Usize => Some(sym::usize),
ty::UintTy::U8 => Some(sym::u8),
ty::UintTy::U16 => Some(sym::u16),
ty::UintTy::U32 => Some(sym::u32),
ty::UintTy::U64 => Some(sym::u64),
ty::UintTy::U128 => Some(sym::u128),
},
_ => None,
}
}
}

/// Extra information about why we ended up with a particular variance.
Expand Down
7 changes: 7 additions & 0 deletions compiler/rustc_passes/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -658,3 +658,10 @@ pub struct CollapseDebuginfo {
#[label]
pub defn_span: Span,
}

#[derive(LintDiagnostic)]
#[diag(passes::deprecated_annotation_has_no_effect)]
pub struct DeprecatedAnnotationHasNoEffect {
#[suggestion(applicability = "machine-applicable", code = "")]
pub span: Span,
}
17 changes: 7 additions & 10 deletions compiler/rustc_passes/src/stability.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
//! A pass that annotates every item and method with its stability level,
//! propagating default levels lexically from parent to children ast nodes.

use crate::errors;
use rustc_attr::{
self as attr, rust_version_symbol, ConstStability, Stability, StabilityLevel, Unstable,
UnstableReason, VERSION_PLACEHOLDER,
Expand Down Expand Up @@ -122,16 +123,12 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {

if kind == AnnotationKind::Prohibited || kind == AnnotationKind::DeprecationProhibited {
let hir_id = self.tcx.hir().local_def_id_to_hir_id(def_id);
self.tcx.struct_span_lint_hir(USELESS_DEPRECATED, hir_id, *span, |lint| {
lint.build("this `#[deprecated]` annotation has no effect")
.span_suggestion_short(
*span,
"remove the unnecessary deprecation attribute",
"",
rustc_errors::Applicability::MachineApplicable,
)
.emit();
});
self.tcx.emit_spanned_lint(
USELESS_DEPRECATED,
hir_id,
*span,
errors::DeprecatedAnnotationHasNoEffect { span: *span },
);
}

// `Deprecation` is just two pointers, no need to intern it
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 @@ -396,6 +396,7 @@ symbols! {
assume_init,
async_await,
async_closure,
async_fn_in_trait,
atomic,
atomic_mod,
atomics,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,12 @@
use crate::abi::Endian;
use crate::spec::{LinkerFlavor, RelroLevel, Target, TargetOptions};
use crate::spec::{LinkerFlavor, Target, TargetOptions};

pub fn target() -> Target {
let mut base = super::linux_gnu_base::opts();
base.cpu = "ppc64".into();
base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]);
base.max_atomic_width = Some(64);

// ld.so in at least RHEL6 on ppc64 has a bug related to BIND_NOW, so only enable partial RELRO
// for now. https://github.com/rust-lang/rust/pull/43170#issuecomment-315411474
base.relro_level = RelroLevel::Partial;

Target {
llvm_target: "powerpc64-unknown-linux-gnu".into(),
pointer_width: 64,
Expand Down
22 changes: 4 additions & 18 deletions compiler/rustc_typeck/src/check/writeback.rs
Original file line number Diff line number Diff line change
Expand Up @@ -717,27 +717,13 @@ impl<'cx, 'tcx> Resolver<'cx, 'tcx> {
Resolver { tcx: fcx.tcx, infcx: fcx, span, body, replaced_with_error: false }
}

fn report_type_error(&self, t: Ty<'tcx>) {
fn report_error(&self, p: impl Into<ty::GenericArg<'tcx>>) {
if !self.tcx.sess.has_errors().is_some() {
self.infcx
.emit_inference_failure_err(
Some(self.body.id()),
self.span.to_span(self.tcx),
t.into(),
E0282,
false,
)
.emit();
}
}

fn report_const_error(&self, c: ty::Const<'tcx>) {
if self.tcx.sess.has_errors().is_none() {
self.infcx
.emit_inference_failure_err(
Some(self.body.id()),
self.span.to_span(self.tcx),
c.into(),
p.into(),
E0282,
false,
)
Expand Down Expand Up @@ -782,7 +768,7 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Resolver<'cx, 'tcx> {
}
Err(_) => {
debug!("Resolver::fold_ty: input type `{:?}` not fully resolvable", t);
self.report_type_error(t);
self.report_error(t);
self.replaced_with_error = true;
self.tcx().ty_error()
}
Expand All @@ -799,7 +785,7 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Resolver<'cx, 'tcx> {
Ok(ct) => self.tcx.erase_regions(ct),
Err(_) => {
debug!("Resolver::fold_const: input const `{:?}` not fully resolvable", ct);
self.report_const_error(ct);
self.report_error(ct);
self.replaced_with_error = true;
self.tcx().const_error(ct.ty())
}
Expand Down
Loading

0 comments on commit 4d44e09

Please sign in to comment.