Auto merge of #100120 - matthiaskrgr:rollup-g6ycykq, r=matthiaskrgr

Rollup of 6 pull requests

Successful merges:

 - #98771 (Add support for link-flavor rust-lld for iOS, tvOS and watchOS)
 - #98835 (relate `closure_substs.parent_substs()` to parent fn in NLL)
 - #99746 (Use `TraitEngine` in more places that don't specifically need `FulfillmentContext::new_in_snapshot`)
 - #99786 (Recover from C++ style `enum struct`)
 - #99795 (Delay a bug when failed to normalize trait ref during specialization)
 - #100029 (Prevent ICE for `doc_alias` on match arm, statement, expression)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2022-08-04 03:52:29 +00:00
commit caee496150
37 changed files with 496 additions and 102 deletions

View File

@ -2619,6 +2619,34 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
);
}
// Now equate closure substs to regions inherited from `typeck_root_def_id`. Fixes #98589.
let typeck_root_def_id = tcx.typeck_root_def_id(self.body.source.def_id());
let typeck_root_substs = ty::InternalSubsts::identity_for_item(tcx, typeck_root_def_id);
let parent_substs = match tcx.def_kind(def_id) {
DefKind::Closure => substs.as_closure().parent_substs(),
DefKind::Generator => substs.as_generator().parent_substs(),
DefKind::InlineConst => substs.as_inline_const().parent_substs(),
other => bug!("unexpected item {:?}", other),
};
let parent_substs = tcx.mk_substs(parent_substs.iter());
assert_eq!(typeck_root_substs.len(), parent_substs.len());
if let Err(_) = self.eq_substs(
typeck_root_substs,
parent_substs,
location.to_locations(),
ConstraintCategory::BoringNoLocation,
) {
span_mirbug!(
self,
def_id,
"could not relate closure to parent {:?} != {:?}",
typeck_root_substs,
parent_substs
);
}
tcx.predicates_of(def_id).instantiate(tcx, substs)
}

View File

@ -38,6 +38,23 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
.relate(a, b)?;
Ok(())
}
/// Add sufficient constraints to ensure `a == b`. See also [Self::relate_types].
pub(super) fn eq_substs(
&mut self,
a: ty::SubstsRef<'tcx>,
b: ty::SubstsRef<'tcx>,
locations: Locations,
category: ConstraintCategory<'tcx>,
) -> Fallible<()> {
TypeRelating::new(
self.infcx,
NllTypeRelatingDelegate::new(self, locations, category, UniverseInfo::other()),
ty::Variance::Invariant,
)
.relate(a, b)?;
Ok(())
}
}
struct NllTypeRelatingDelegate<'me, 'bccx, 'tcx> {

View File

@ -2675,7 +2675,7 @@ fn add_apple_sdk(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) {
let llvm_target = &sess.target.llvm_target;
if sess.target.vendor != "apple"
|| !matches!(os.as_ref(), "ios" | "tvos" | "watchos")
|| flavor != LinkerFlavor::Gcc
|| (flavor != LinkerFlavor::Gcc && flavor != LinkerFlavor::Lld(LldFlavor::Ld64))
{
return;
}
@ -2706,13 +2706,16 @@ fn add_apple_sdk(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) {
return;
}
};
if llvm_target.contains("macabi") {
cmd.args(&["-target", llvm_target])
} else {
let arch_name = llvm_target.split('-').next().expect("LLVM target must have a hyphen");
cmd.args(&["-arch", arch_name])
match flavor {
LinkerFlavor::Gcc => {
cmd.args(&["-isysroot", &sdk_root, "-Wl,-syslibroot", &sdk_root]);
}
LinkerFlavor::Lld(LldFlavor::Ld64) => {
cmd.args(&["-syslibroot", &sdk_root]);
}
_ => unreachable!(),
}
cmd.args(&["-isysroot", &sdk_root, "-Wl,-syslibroot", &sdk_root]);
}
fn get_apple_sdk_root(sdk_name: &str) -> Result<String, String> {

View File

@ -10,7 +10,7 @@ use rustc_middle::mir::*;
use rustc_middle::ty::{self, subst::SubstsRef, AdtDef, Ty};
use rustc_span::DUMMY_SP;
use rustc_trait_selection::traits::{
self, FulfillmentContext, ImplSource, Obligation, ObligationCause, SelectionContext,
self, ImplSource, Obligation, ObligationCause, SelectionContext, TraitEngineExt,
};
use super::ConstCx;
@ -191,7 +191,7 @@ impl Qualif for NeedsNonConstDrop {
// If we successfully found one, then select all of the predicates
// implied by our const drop impl.
let mut fcx = FulfillmentContext::new();
let mut fcx = <dyn TraitEngine<'tcx>>::new(cx.tcx);
for nested in impl_src.nested_obligations() {
fcx.register_predicate_obligation(&infcx, nested);
}

View File

@ -60,51 +60,7 @@ pub enum Target {
impl Display for Target {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"{}",
match *self {
Target::ExternCrate => "extern crate",
Target::Use => "use",
Target::Static => "static item",
Target::Const => "constant item",
Target::Fn => "function",
Target::Closure => "closure",
Target::Mod => "module",
Target::ForeignMod => "foreign module",
Target::GlobalAsm => "global asm",
Target::TyAlias => "type alias",
Target::OpaqueTy => "opaque type",
Target::Enum => "enum",
Target::Variant => "enum variant",
Target::Struct => "struct",
Target::Field => "struct field",
Target::Union => "union",
Target::Trait => "trait",
Target::TraitAlias => "trait alias",
Target::Impl => "item",
Target::Expression => "expression",
Target::Statement => "statement",
Target::Arm => "match arm",
Target::AssocConst => "associated const",
Target::Method(kind) => match kind {
MethodKind::Inherent => "inherent method",
MethodKind::Trait { body: false } => "required trait method",
MethodKind::Trait { body: true } => "provided trait method",
},
Target::AssocTy => "associated type",
Target::ForeignFn => "foreign function",
Target::ForeignStatic => "foreign static item",
Target::ForeignTy => "foreign type",
Target::GenericParam(kind) => match kind {
GenericParamKind::Type => "type parameter",
GenericParamKind::Lifetime => "lifetime parameter",
GenericParamKind::Const => "const parameter",
},
Target::MacroDef => "macro def",
Target::Param => "function param",
}
)
write!(f, "{}", Self::name(*self))
}
}
@ -185,4 +141,48 @@ impl Target {
hir::GenericParamKind::Const { .. } => Target::GenericParam(GenericParamKind::Const),
}
}
pub fn name(self) -> &'static str {
match self {
Target::ExternCrate => "extern crate",
Target::Use => "use",
Target::Static => "static item",
Target::Const => "constant item",
Target::Fn => "function",
Target::Closure => "closure",
Target::Mod => "module",
Target::ForeignMod => "foreign module",
Target::GlobalAsm => "global asm",
Target::TyAlias => "type alias",
Target::OpaqueTy => "opaque type",
Target::Enum => "enum",
Target::Variant => "enum variant",
Target::Struct => "struct",
Target::Field => "struct field",
Target::Union => "union",
Target::Trait => "trait",
Target::TraitAlias => "trait alias",
Target::Impl => "implementation block",
Target::Expression => "expression",
Target::Statement => "statement",
Target::Arm => "match arm",
Target::AssocConst => "associated const",
Target::Method(kind) => match kind {
MethodKind::Inherent => "inherent method",
MethodKind::Trait { body: false } => "required trait method",
MethodKind::Trait { body: true } => "provided trait method",
},
Target::AssocTy => "associated type",
Target::ForeignFn => "foreign function",
Target::ForeignStatic => "foreign static item",
Target::ForeignTy => "foreign type",
Target::GenericParam(kind) => match kind {
GenericParamKind::Type => "type parameter",
GenericParamKind::Lifetime => "lifetime parameter",
GenericParamKind::Const => "const parameter",
},
Target::MacroDef => "macro def",
Target::Param => "function param",
}
}
}

View File

@ -1216,6 +1216,25 @@ impl<'a> Parser<'a> {
/// Parses an enum declaration.
fn parse_item_enum(&mut self) -> PResult<'a, ItemInfo> {
if self.token.is_keyword(kw::Struct) {
let mut err = self.struct_span_err(
self.prev_token.span.to(self.token.span),
"`enum` and `struct` are mutually exclusive",
);
err.span_suggestion(
self.prev_token.span.to(self.token.span),
"replace `enum struct` with",
"enum",
Applicability::MachineApplicable,
);
if self.look_ahead(1, |t| t.is_ident()) {
self.bump();
err.emit();
} else {
return Err(err);
}
}
let id = self.parse_ident()?;
let mut generics = self.parse_generics()?;
generics.where_clause = self.parse_where_clause()?;

View File

@ -596,8 +596,6 @@ impl CheckAttrVisitor<'_> {
let span = meta.span();
if let Some(location) = match target {
Target::Impl => Some("implementation block"),
Target::ForeignMod => Some("extern block"),
Target::AssocTy => {
let parent_hir_id = self.tcx.hir().get_parent_item(hir_id);
let containing_item = self.tcx.hir().expect_item(parent_hir_id);
@ -619,7 +617,34 @@ impl CheckAttrVisitor<'_> {
}
// we check the validity of params elsewhere
Target::Param => return false,
_ => None,
Target::Expression
| Target::Statement
| Target::Arm
| Target::ForeignMod
| Target::Closure
| Target::Impl => Some(target.name()),
Target::ExternCrate
| Target::Use
| Target::Static
| Target::Const
| Target::Fn
| Target::Mod
| Target::GlobalAsm
| Target::TyAlias
| Target::OpaqueTy
| Target::Enum
| Target::Variant
| Target::Struct
| Target::Field
| Target::Union
| Target::Trait
| Target::TraitAlias
| Target::Method(..)
| Target::ForeignFn
| Target::ForeignStatic
| Target::ForeignTy
| Target::GenericParam(..)
| Target::MacroDef => None,
} {
tcx.sess.emit_err(errors::DocAliasBadLocation { span, attr_str, location });
return false;

View File

@ -1,9 +1,14 @@
use super::apple_sdk_base::{opts, Arch};
use crate::spec::{FramePointer, Target, TargetOptions};
use crate::spec::{FramePointer, LinkerFlavor, Target, TargetOptions};
pub fn target() -> Target {
let llvm_target = "arm64-apple-ios14.0-macabi";
let mut base = opts("ios", Arch::Arm64_macabi);
base.add_pre_link_args(LinkerFlavor::Gcc, &["-target", llvm_target]);
Target {
llvm_target: "arm64-apple-ios14.0-macabi".into(),
llvm_target: llvm_target.into(),
pointer_width: 64,
data_layout: "e-m:o-i64:64-i128:128-n32:64-S128".into(),
arch: "aarch64".into(),
@ -21,7 +26,7 @@ pub fn target() -> Target {
-disable-llvm-passes\0\
-Os\0"
.into(),
..opts("ios", Arch::Arm64_macabi)
..base
},
}
}

View File

@ -109,15 +109,34 @@ pub fn ios_llvm_target(arch: &str) -> String {
format!("{}-apple-ios{}.{}.0", arch, major, minor)
}
pub fn ios_lld_platform_version() -> String {
let (major, minor) = ios_deployment_target();
format!("{}.{}", major, minor)
}
pub fn ios_sim_llvm_target(arch: &str) -> String {
let (major, minor) = ios_deployment_target();
format!("{}-apple-ios{}.{}.0-simulator", arch, major, minor)
}
fn tvos_deployment_target() -> (u32, u32) {
deployment_target("TVOS_DEPLOYMENT_TARGET").unwrap_or((7, 0))
}
pub fn tvos_lld_platform_version() -> String {
let (major, minor) = tvos_deployment_target();
format!("{}.{}", major, minor)
}
fn watchos_deployment_target() -> (u32, u32) {
deployment_target("WATCHOS_DEPLOYMENT_TARGET").unwrap_or((5, 0))
}
pub fn watchos_lld_platform_version() -> String {
let (major, minor) = watchos_deployment_target();
format!("{}.{}", major, minor)
}
pub fn watchos_sim_llvm_target(arch: &str) -> String {
let (major, minor) = watchos_deployment_target();
format!("{}-apple-watchos{}.{}.0-simulator", arch, major, minor)

View File

@ -1,4 +1,4 @@
use crate::{spec::cvs, spec::TargetOptions};
use crate::spec::{cvs, LinkArgs, LinkerFlavor, LldFlavor, TargetOptions};
use std::borrow::Cow;
use Arch::*;
@ -17,6 +17,18 @@ pub enum Arch {
Arm64_sim,
}
fn target_arch_name(arch: Arch) -> &'static str {
match arch {
Armv7 => "armv7",
Armv7k => "armv7k",
Armv7s => "armv7s",
Arm64 | Arm64_macabi | Arm64_sim => "arm64",
Arm64_32 => "arm64_32",
I386 => "i386",
X86_64 | X86_64_macabi => "x86_64",
}
}
fn target_abi(arch: Arch) -> &'static str {
match arch {
Armv7 | Armv7k | Armv7s | Arm64 | Arm64_32 | I386 | X86_64 => "",
@ -49,11 +61,51 @@ fn link_env_remove(arch: Arch) -> Cow<'static, [Cow<'static, str>]> {
}
}
fn pre_link_args(os: &'static str, arch: Arch) -> LinkArgs {
let mut args = LinkArgs::new();
let target_abi = target_abi(arch);
let platform_name = match target_abi {
"sim" => format!("{}-simulator", os),
"macabi" => "mac-catalyst".to_string(),
_ => os.to_string(),
};
let platform_version = match os.as_ref() {
"ios" => super::apple_base::ios_lld_platform_version(),
"tvos" => super::apple_base::tvos_lld_platform_version(),
"watchos" => super::apple_base::watchos_lld_platform_version(),
_ => unreachable!(),
};
let arch_str = target_arch_name(arch);
if target_abi != "macabi" {
args.insert(LinkerFlavor::Gcc, vec!["-arch".into(), arch_str.into()]);
}
args.insert(
LinkerFlavor::Lld(LldFlavor::Ld64),
vec![
"-arch".into(),
arch_str.into(),
"-platform_version".into(),
platform_name.into(),
platform_version.clone().into(),
platform_version.into(),
],
);
args
}
pub fn opts(os: &'static str, arch: Arch) -> TargetOptions {
TargetOptions {
abi: target_abi(arch).into(),
cpu: target_cpu(arch).into(),
dynamic_linking: false,
pre_link_args: pre_link_args(os, arch),
link_env_remove: link_env_remove(arch),
has_thread_local: false,
..super::apple_base::opts(os)

View File

@ -46,7 +46,10 @@ impl Target {
)
}
(LinkerFlavor::Gcc, LldFlavor::Ld64) => {
assert_matches!(flavor, LinkerFlavor::Gcc)
assert_matches!(
flavor,
LinkerFlavor::Lld(LldFlavor::Ld64) | LinkerFlavor::Gcc
)
}
(LinkerFlavor::Msvc | LinkerFlavor::Lld(LldFlavor::Link), LldFlavor::Link) => {
assert_matches!(

View File

@ -1,10 +1,14 @@
use super::apple_sdk_base::{opts, Arch};
use crate::spec::{StackProbeType, Target, TargetOptions};
use crate::spec::{LinkerFlavor, StackProbeType, Target, TargetOptions};
pub fn target() -> Target {
let base = opts("ios", Arch::X86_64_macabi);
let llvm_target = "x86_64-apple-ios13.0-macabi";
let mut base = opts("ios", Arch::X86_64_macabi);
base.add_pre_link_args(LinkerFlavor::Gcc, &["-target", llvm_target]);
Target {
llvm_target: "x86_64-apple-ios13.0-macabi".into(),
llvm_target: llvm_target.into(),
pointer_width: 64,
data_layout: "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
.into(),

View File

@ -205,7 +205,7 @@ impl<'tcx> AutoTraitFinder<'tcx> {
// At this point, we already have all of the bounds we need. FulfillmentContext is used
// to store all of the necessary region/lifetime bounds in the InferContext, as well as
// an additional sanity check.
let mut fulfill = FulfillmentContext::new();
let mut fulfill = <dyn TraitEngine<'tcx>>::new(tcx);
fulfill.register_bound(&infcx, full_env, ty, trait_did, ObligationCause::dummy());
let errors = fulfill.select_all_or_error(&infcx);

View File

@ -5,7 +5,7 @@
use crate::infer::{DefiningAnchor, TyCtxtInferExt};
use crate::traits::{
FulfillmentContext, ImplSource, Obligation, ObligationCause, SelectionContext, TraitEngine,
ImplSource, Obligation, ObligationCause, SelectionContext, TraitEngine, TraitEngineExt,
Unimplemented,
};
use rustc_middle::traits::CodegenObligationError;
@ -53,7 +53,7 @@ pub fn codegen_fulfill_obligation<'tcx>(
// Currently, we use a fulfillment context to completely resolve
// all nested obligations. This is because they can inform the
// inference of the impl's type parameters.
let mut fulfill_cx = FulfillmentContext::new();
let mut fulfill_cx = <dyn TraitEngine<'tcx>>::new(tcx);
let impl_source = selection.map(|predicate| {
fulfill_cx.register_predicate_obligation(&infcx, predicate);
});

View File

@ -11,7 +11,7 @@ use crate::traits::util::impl_subject_and_oblig;
use crate::traits::SkipLeakCheck;
use crate::traits::{
self, FulfillmentContext, Normalized, Obligation, ObligationCause, PredicateObligation,
PredicateObligations, SelectionContext,
PredicateObligations, SelectionContext, TraitEngineExt,
};
use rustc_data_structures::fx::FxIndexSet;
use rustc_errors::Diagnostic;
@ -385,7 +385,7 @@ fn resolve_negative_obligation<'cx, 'tcx>(
return false;
};
let mut fulfillment_cx = FulfillmentContext::new();
let mut fulfillment_cx = <dyn TraitEngine<'tcx>>::new(infcx.tcx);
fulfillment_cx.register_predicate_obligation(infcx, o);
let errors = fulfillment_cx.select_all_or_error(infcx);

View File

@ -164,7 +164,7 @@ pub fn type_known_to_meet_bound_modulo_regions<'a, 'tcx>(
// The handling of regions in this area of the code is terrible,
// see issue #29149. We should be able to improve on this with
// NLL.
let mut fulfill_cx = FulfillmentContext::new();
let mut fulfill_cx = <dyn TraitEngine<'tcx>>::new(infcx.tcx);
// We can use a dummy node-id here because we won't pay any mind
// to region obligations that arise (there shouldn't really be any

View File

@ -14,7 +14,9 @@ use specialization_graph::GraphExt;
use crate::infer::{InferCtxt, InferOk, TyCtxtInferExt};
use crate::traits::select::IntercrateAmbiguityCause;
use crate::traits::{self, coherence, FutureCompatOverlapErrorKind, ObligationCause, TraitEngine};
use crate::traits::{
self, coherence, FutureCompatOverlapErrorKind, ObligationCause, TraitEngine, TraitEngineExt,
};
use rustc_data_structures::fx::{FxHashSet, FxIndexSet};
use rustc_errors::{struct_span_err, EmissionGuarantee, LintDiagnosticBuilder};
use rustc_hir::def_id::{DefId, LocalDefId};
@ -24,8 +26,8 @@ use rustc_session::lint::builtin::COHERENCE_LEAK_CHECK;
use rustc_session::lint::builtin::ORDER_DEPENDENT_TRAIT_OBJECTS;
use rustc_span::{Span, DUMMY_SP};
use super::util;
use super::{FulfillmentContext, SelectionContext};
use super::SelectionContext;
use super::{util, FulfillmentContext};
/// Information pertinent to an overlapping impl error.
#[derive(Debug)]
@ -149,8 +151,6 @@ pub(super) fn specializes(tcx: TyCtxt<'_>, (impl1_def_id, impl2_def_id): (DefId,
// Create an infcx, taking the predicates of impl1 as assumptions:
tcx.infer_ctxt().enter(|infcx| {
// Normalize the trait reference. The WF rules ought to ensure
// that this always succeeds.
let impl1_trait_ref = match traits::fully_normalize(
&infcx,
FulfillmentContext::new(),
@ -159,8 +159,12 @@ pub(super) fn specializes(tcx: TyCtxt<'_>, (impl1_def_id, impl2_def_id): (DefId,
impl1_trait_ref,
) {
Ok(impl1_trait_ref) => impl1_trait_ref,
Err(err) => {
bug!("failed to fully normalize {:?}: {:?}", impl1_trait_ref, err);
Err(_errors) => {
tcx.sess.delay_span_bug(
tcx.def_span(impl1_def_id),
format!("failed to fully normalize {impl1_trait_ref}"),
);
impl1_trait_ref
}
};
@ -207,7 +211,7 @@ fn fulfill_implication<'a, 'tcx>(
// (which are packed up in penv)
infcx.save_and_restore_in_snapshot_flag(|infcx| {
let mut fulfill_cx = FulfillmentContext::new();
let mut fulfill_cx = <dyn TraitEngine<'tcx>>::new(infcx.tcx);
for oblig in obligations.chain(more_obligations) {
fulfill_cx.register_predicate_obligation(&infcx, oblig);
}

View File

@ -1,6 +1,6 @@
use crate::infer::{InferCtxt, TyCtxtInferExt};
use crate::traits::ObligationCause;
use crate::traits::{self, TraitEngine};
use crate::traits::{TraitEngine, TraitEngineExt};
use rustc_data_structures::fx::FxHashSet;
use rustc_hir as hir;
@ -72,7 +72,7 @@ fn type_marked_structural<'tcx>(
adt_ty: Ty<'tcx>,
cause: ObligationCause<'tcx>,
) -> bool {
let mut fulfillment_cx = traits::FulfillmentContext::new();
let mut fulfillment_cx = <dyn TraitEngine<'tcx>>::new(infcx.tcx);
// require `#[derive(PartialEq)]`
let structural_peq_def_id =
infcx.tcx.require_lang_item(LangItem::StructuralPeq, Some(cause.span));

View File

@ -14,8 +14,7 @@ use rustc_span::source_map::DUMMY_SP;
use rustc_trait_selection::infer::InferCtxtBuilderExt;
use rustc_trait_selection::traits::query::{CanonicalTyGoal, Fallible, NoSolution};
use rustc_trait_selection::traits::wf;
use rustc_trait_selection::traits::FulfillmentContext;
use rustc_trait_selection::traits::TraitEngine;
use rustc_trait_selection::traits::{TraitEngine, TraitEngineExt};
use smallvec::{smallvec, SmallVec};
pub(crate) fn provide(p: &mut Providers) {
@ -52,7 +51,7 @@ fn compute_implied_outlives_bounds<'tcx>(
let mut implied_bounds = vec![];
let mut fulfill_cx = FulfillmentContext::new();
let mut fulfill_cx = <dyn TraitEngine<'tcx>>::new(tcx);
while let Some(arg) = wf_args.pop() {
if !checked_wf_args.insert(arg) {

View File

@ -109,7 +109,7 @@ fn visit_implementation_of_copy(tcx: TyCtxt<'_>, impl_did: LocalDefId) {
// it is not immediately clear why Copy is not implemented for a field, since
// all we point at is the field itself.
tcx.infer_ctxt().ignoring_regions().enter(|infcx| {
let mut fulfill_cx = traits::FulfillmentContext::new();
let mut fulfill_cx = <dyn TraitEngine<'_>>::new(tcx);
fulfill_cx.register_bound(
&infcx,
param_env,

View File

@ -7,7 +7,7 @@ use rustc_infer::traits::TraitEngine;
use rustc_infer::traits::{ObligationCause, WellFormedLoc};
use rustc_middle::ty::query::Providers;
use rustc_middle::ty::{self, Region, ToPredicate, TyCtxt, TypeFoldable, TypeFolder};
use rustc_trait_selection::traits;
use rustc_trait_selection::traits::{self, TraitEngineExt};
pub fn provide(providers: &mut Providers) {
*providers = Providers { diagnostic_hir_wf_check, ..*providers };
@ -66,7 +66,7 @@ fn diagnostic_hir_wf_check<'tcx>(
impl<'tcx> Visitor<'tcx> for HirWfCheck<'tcx> {
fn visit_ty(&mut self, ty: &'tcx hir::Ty<'tcx>) {
self.tcx.infer_ctxt().enter(|infcx| {
let mut fulfill = traits::FulfillmentContext::new();
let mut fulfill = <dyn TraitEngine<'tcx>>::new(self.tcx);
let tcx_ty =
self.icx.to_ty(ty).fold_with(&mut EraseAllBoundRegions { tcx: self.tcx });
let cause = traits::ObligationCause::new(

View File

@ -3,7 +3,7 @@ use rustc_middle::ty::{self, Ty};
use rustc_trait_selection::infer::InferCtxt;
use rustc_trait_selection::traits::query::type_op::{self, TypeOp, TypeOpOutput};
use rustc_trait_selection::traits::query::NoSolution;
use rustc_trait_selection::traits::{FulfillmentContext, ObligationCause, TraitEngine};
use rustc_trait_selection::traits::{ObligationCause, TraitEngine, TraitEngineExt};
pub use rustc_middle::traits::query::OutlivesBound;
@ -63,7 +63,7 @@ impl<'cx, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'cx, 'tcx> {
if let Some(constraints) = constraints {
// Instantiation may have produced new inference variables and constraints on those
// variables. Process these constraints.
let mut fulfill_cx = FulfillmentContext::new();
let mut fulfill_cx = <dyn TraitEngine<'tcx>>::new(self.tcx);
let cause = ObligationCause::misc(span, body_id);
for &constraint in &constraints.outlives {
let obligation = self.query_outlives_constraint_to_obligation(

View File

@ -24,7 +24,10 @@ pub(crate) struct AutoTraitFinder<'a, 'tcx> {
pub(crate) cx: &'a mut core::DocContext<'tcx>,
}
impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx>
where
'tcx: 'a, // should be an implied bound; rustc bug #98852.
{
pub(crate) fn new(cx: &'a mut core::DocContext<'tcx>) -> Self {
AutoTraitFinder { cx }
}

View File

@ -1,4 +1,4 @@
error: `#[doc(alias = "...")]` isn't allowed on extern block
error: `#[doc(alias = "...")]` isn't allowed on foreign module
--> $DIR/check-doc-alias-attr-location.rs:7:7
|
LL | #[doc(alias = "foo")]

View File

@ -212,7 +212,7 @@ note: the lint level is defined here
LL | #![warn(unused_attributes, unknown_lints)]
| ^^^^^^^^^^^^^^^^^
warning: `#[automatically_derived]` only has an effect on items
warning: `#[automatically_derived]` only has an effect on implementation blocks
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:266:1
|
LL | #[automatically_derived]
@ -515,25 +515,25 @@ warning: `#[path]` only has an effect on modules
LL | #[path = "3800"] impl S { }
| ^^^^^^^^^^^^^^^^
warning: `#[automatically_derived]` only has an effect on items
warning: `#[automatically_derived]` only has an effect on implementation blocks
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:269:17
|
LL | mod inner { #![automatically_derived] }
| ^^^^^^^^^^^^^^^^^^^^^^^^^
warning: `#[automatically_derived]` only has an effect on items
warning: `#[automatically_derived]` only has an effect on implementation blocks
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:272:5
|
LL | #[automatically_derived] fn f() { }
| ^^^^^^^^^^^^^^^^^^^^^^^^
warning: `#[automatically_derived]` only has an effect on items
warning: `#[automatically_derived]` only has an effect on implementation blocks
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:275:5
|
LL | #[automatically_derived] struct S;
| ^^^^^^^^^^^^^^^^^^^^^^^^
warning: `#[automatically_derived]` only has an effect on items
warning: `#[automatically_derived]` only has an effect on implementation blocks
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:278:5
|
LL | #[automatically_derived] type T = S;
@ -923,7 +923,7 @@ warning: `#[must_use]` has no effect when applied to a type alias
LL | #[must_use] type T = S;
| ^^^^^^^^^^^
warning: `#[must_use]` has no effect when applied to an item
warning: `#[must_use]` has no effect when applied to an implementation block
--> $DIR/issue-43106-gating-of-builtin-attrs.rs:614:5
|
LL | #[must_use] impl S { }

View File

@ -45,7 +45,7 @@ error: `#[must_use]` has no effect when applied to a static item
LL | #[must_use]
| ^^^^^^^^^^^
error: `#[must_use]` has no effect when applied to an item
error: `#[must_use]` has no effect when applied to an implementation block
--> $DIR/unused_attributes-must_use.rs:33:1
|
LL | #[must_use]
@ -69,7 +69,7 @@ error: `#[must_use]` has no effect when applied to a type parameter
LL | fn qux<#[must_use] T>(_: T) {}
| ^^^^^^^^^^^
error: `#[must_use]` has no effect when applied to an item
error: `#[must_use]` has no effect when applied to an implementation block
--> $DIR/unused_attributes-must_use.rs:79:1
|
LL | #[must_use]

View File

@ -0,0 +1,36 @@
// Regression test for #98589.
// Previously, named lifetime `'a` that appears in the closure was unrelated to `'a`
// that appears in the parent function iff `'a` is early-bound.
// This made the following tests pass borrowck.
// check-fail
// The bound `'a: 'a` ensures that `'a` is early-bound.
fn test_early_early<'a: 'a, 'b: 'b>() {
|| { None::<&'a &'b ()>; };
//~^ ERROR lifetime may not live long enough
}
fn test_early_late<'a: 'a, 'b>() {
|| { None::<&'a &'b ()>; };
//~^ ERROR lifetime may not live long enough
}
// No early-bound lifetime; included for completeness.
fn test_late_late<'a, 'b>() {
|| { None::<&'a &'b ()>; };
//~^ ERROR lifetime may not live long enough
}
fn test_early_type<'a: 'a, T>() {
|| { None::<&'a T>; };
//~^ ERROR the parameter type `T` may not live long enough
}
// No early-bound lifetime; included for completeness.
fn test_late_type<'a, T>() {
|| { None::<&'a T>; };
//~^ ERROR the parameter type `T` may not live long enough
}
fn main() {}

View File

@ -0,0 +1,61 @@
error: lifetime may not live long enough
--> $DIR/issue-98589-closures-relate-named-regions.rs:10:5
|
LL | fn test_early_early<'a: 'a, 'b: 'b>() {
| -- -- lifetime `'b` defined here
| |
| lifetime `'a` defined here
LL | || { None::<&'a &'b ()>; };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'b` must outlive `'a`
|
= help: consider adding the following bound: `'b: 'a`
error: lifetime may not live long enough
--> $DIR/issue-98589-closures-relate-named-regions.rs:15:10
|
LL | fn test_early_late<'a: 'a, 'b>() {
| -- -- lifetime `'b` defined here
| |
| lifetime `'a` defined here
LL | || { None::<&'a &'b ()>; };
| ^^^^^^^^^^^^^^^^^^ requires that `'b` must outlive `'a`
|
= help: consider adding the following bound: `'b: 'a`
error: lifetime may not live long enough
--> $DIR/issue-98589-closures-relate-named-regions.rs:21:10
|
LL | fn test_late_late<'a, 'b>() {
| -- -- lifetime `'b` defined here
| |
| lifetime `'a` defined here
LL | || { None::<&'a &'b ()>; };
| ^^^^^^^^^^^^^^^^^^ requires that `'b` must outlive `'a`
|
= help: consider adding the following bound: `'b: 'a`
error[E0309]: the parameter type `T` may not live long enough
--> $DIR/issue-98589-closures-relate-named-regions.rs:26:5
|
LL | || { None::<&'a T>; };
| ^^^^^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds
|
help: consider adding an explicit lifetime bound...
|
LL | fn test_early_type<'a: 'a, T: 'a>() {
| ++++
error[E0309]: the parameter type `T` may not live long enough
--> $DIR/issue-98589-closures-relate-named-regions.rs:32:5
|
LL | || { None::<&'a T>; };
| ^^^^^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds
|
help: consider adding an explicit lifetime bound...
|
LL | fn test_late_type<'a, T: 'a>() {
| ++++
error: aborting due to 5 previous errors
For more information about this error, try `rustc --explain E0309`.

View File

@ -0,0 +1,13 @@
// run-rustfix
pub enum Range {
//~^ ERROR `enum` and `struct` are mutually exclusive
Valid {
begin: u32,
len: u32,
},
Out,
}
fn main() {
}

View File

@ -0,0 +1,13 @@
// run-rustfix
pub enum struct Range {
//~^ ERROR `enum` and `struct` are mutually exclusive
Valid {
begin: u32,
len: u32,
},
Out,
}
fn main() {
}

View File

@ -0,0 +1,8 @@
error: `enum` and `struct` are mutually exclusive
--> $DIR/issue-99625-enum-struct-mutually-exclusive.rs:3:5
|
LL | pub enum struct Range {
| ^^^^^^^^^^^ help: replace `enum struct` with: `enum`
error: aborting due to previous error

View File

@ -21,6 +21,12 @@ impl Foo for Bar {
type X = i32;
fn foo(#[doc(alias = "qux")] _x: u32) -> Self::X {
//~^ ERROR
0
#[doc(alias = "stmt")] //~ ERROR
let x = 0;
#[doc(alias = "expr")] //~ ERROR
match x {
#[doc(alias = "arm")] //~ ERROR
_ => 0
}
}
}

View File

@ -4,7 +4,7 @@ error: allow, cfg, cfg_attr, deny, expect, forbid, and warn are the only allowed
LL | fn foo(#[doc(alias = "qux")] _x: u32) -> Self::X {
| ^^^^^^^^^^^^^^^^^^^^^
error: `#[doc(alias = "...")]` isn't allowed on extern block
error: `#[doc(alias = "...")]` isn't allowed on foreign module
--> $DIR/check-doc-alias-attr-location.rs:9:7
|
LL | #[doc(alias = "foo")]
@ -28,5 +28,23 @@ error: `#[doc(alias = "...")]` isn't allowed on type alias in implementation blo
LL | #[doc(alias = "assoc")]
| ^^^^^^^^^^^^^^^
error: aborting due to 5 previous errors
error: `#[doc(alias = "...")]` isn't allowed on statement
--> $DIR/check-doc-alias-attr-location.rs:24:15
|
LL | #[doc(alias = "stmt")]
| ^^^^^^^^^^^^^^
error: `#[doc(alias = "...")]` isn't allowed on expression
--> $DIR/check-doc-alias-attr-location.rs:26:15
|
LL | #[doc(alias = "expr")]
| ^^^^^^^^^^^^^^
error: `#[doc(alias = "...")]` isn't allowed on match arm
--> $DIR/check-doc-alias-attr-location.rs:28:19
|
LL | #[doc(alias = "arm")]
| ^^^^^^^^^^^^^
error: aborting due to 8 previous errors

View File

@ -0,0 +1,20 @@
#![feature(specialization)]
#![allow(incomplete_features)]
trait X {}
trait Y: X {}
trait Z {
type Assoc: Y;
}
struct A<T>(T);
impl<T> Y for T where T: X {}
impl<T: X> Z for A<T> {
type Assoc = T;
}
// this impl is invalid, but causes an ICE anyway
impl<T> From<<A<T> as Z>::Assoc> for T {}
//~^ ERROR type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct<T>`)
fn main() {}

View File

@ -0,0 +1,12 @@
error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct<T>`)
--> $DIR/issue-43037.rs:17:6
|
LL | impl<T> From<<A<T> as Z>::Assoc> for T {}
| ^ type parameter `T` must be used as the type parameter for some local type
|
= note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local
= note: only traits defined in the current crate can be implemented for a type parameter
error: aborting due to previous error
For more information about this error, try `rustc --explain E0210`.

View File

@ -0,0 +1,12 @@
//~ ERROR overflow evaluating the requirement `T: Trait<_>`
#![feature(specialization)]
#![allow(incomplete_features)]
pub trait Trait<T> {}
default impl<T, U> Trait<T> for U {}
impl<T> Trait<<T as Iterator>::Item> for T {}
fn main() {}

View File

@ -0,0 +1,14 @@
error[E0275]: overflow evaluating the requirement `T: Trait<_>`
|
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_45814`)
note: required because of the requirements on the impl of `Trait<_>` for `T`
--> $DIR/issue-45814.rs:8:20
|
LL | default impl<T, U> Trait<T> for U {}
| ^^^^^^^^ ^
= note: 128 redundant requirements hidden
= note: required because of the requirements on the impl of `Trait<_>` for `T`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0275`.