mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-06 20:13:42 +00:00
Auto merge of #88061 - jackh726:genericbound-cleanup, r=estebank
Remove `hir::GenericBound::Unsized` Rather than "moving" the `?Sized` bounds to the param bounds, just also check where clauses in `astconv`. I also did some related cleanup here, but that's not strictly neccesary. Also going to do a perf run here. r? `@estebank`
This commit is contained in:
commit
72969f6526
@ -2,7 +2,6 @@ use super::{AnonymousLifetimeMode, LoweringContext, ParamMode};
|
||||
use super::{ImplTraitContext, ImplTraitPosition};
|
||||
use crate::Arena;
|
||||
|
||||
use rustc_ast::node_id::NodeMap;
|
||||
use rustc_ast::ptr::P;
|
||||
use rustc_ast::visit::{self, AssocCtxt, FnCtxt, FnKind, Visitor};
|
||||
use rustc_ast::*;
|
||||
@ -1351,8 +1350,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
generics: &Generics,
|
||||
itctx: ImplTraitContext<'_, 'hir>,
|
||||
) -> GenericsCtor<'hir> {
|
||||
// Collect `?Trait` bounds in where clause and move them to parameter definitions.
|
||||
let mut add_bounds: NodeMap<Vec<_>> = Default::default();
|
||||
// Error if `?Trait` bounds in where clauses don't refer directly to type paramters.
|
||||
// Note: we used to clone these bounds directly onto the type parameter (and avoid lowering
|
||||
// these into hir when we lower thee where clauses), but this makes it quite difficult to
|
||||
// keep track of the Span info. Now, `add_implicitly_sized` in `AstConv` checks both param bounds and
|
||||
// where clauses for `?Sized`.
|
||||
for pred in &generics.where_clause.predicates {
|
||||
if let WherePredicate::BoundPredicate(ref bound_pred) = *pred {
|
||||
'next_bound: for bound in &bound_pred.bounds {
|
||||
@ -1368,7 +1370,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
{
|
||||
for param in &generics.params {
|
||||
if def_id == self.resolver.local_def_id(param.id).to_def_id() {
|
||||
add_bounds.entry(param.id).or_default().push(bound.clone());
|
||||
continue 'next_bound;
|
||||
}
|
||||
}
|
||||
@ -1386,7 +1387,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
}
|
||||
|
||||
GenericsCtor {
|
||||
params: self.lower_generic_params_mut(&generics.params, &add_bounds, itctx).collect(),
|
||||
params: self.lower_generic_params_mut(&generics.params, itctx).collect(),
|
||||
where_clause: self.lower_where_clause(&generics.where_clause),
|
||||
span: self.lower_span(generics.span),
|
||||
}
|
||||
@ -1419,32 +1420,17 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
ref bounded_ty,
|
||||
ref bounds,
|
||||
span,
|
||||
}) => {
|
||||
self.with_in_scope_lifetime_defs(&bound_generic_params, |this| {
|
||||
hir::WherePredicate::BoundPredicate(hir::WhereBoundPredicate {
|
||||
bound_generic_params: this.lower_generic_params(
|
||||
bound_generic_params,
|
||||
&NodeMap::default(),
|
||||
ImplTraitContext::disallowed(),
|
||||
),
|
||||
bounded_ty: this.lower_ty(bounded_ty, ImplTraitContext::disallowed()),
|
||||
bounds: this.arena.alloc_from_iter(bounds.iter().map(
|
||||
|bound| match bound {
|
||||
// We used to ignore `?Trait` bounds, as they were copied into type
|
||||
// parameters already, but we need to keep them around only for
|
||||
// diagnostics when we suggest removal of `?Sized` bounds. See
|
||||
// `suggest_constraining_type_param`. This will need to change if
|
||||
// we ever allow something *other* than `?Sized`.
|
||||
GenericBound::Trait(p, TraitBoundModifier::Maybe) => {
|
||||
hir::GenericBound::Unsized(this.lower_span(p.span))
|
||||
}
|
||||
_ => this.lower_param_bound(bound, ImplTraitContext::disallowed()),
|
||||
},
|
||||
)),
|
||||
span: this.lower_span(span),
|
||||
})
|
||||
}) => self.with_in_scope_lifetime_defs(&bound_generic_params, |this| {
|
||||
hir::WherePredicate::BoundPredicate(hir::WhereBoundPredicate {
|
||||
bound_generic_params: this
|
||||
.lower_generic_params(bound_generic_params, ImplTraitContext::disallowed()),
|
||||
bounded_ty: this.lower_ty(bounded_ty, ImplTraitContext::disallowed()),
|
||||
bounds: this.arena.alloc_from_iter(bounds.iter().map(|bound| {
|
||||
this.lower_param_bound(bound, ImplTraitContext::disallowed())
|
||||
})),
|
||||
span: this.lower_span(span),
|
||||
})
|
||||
}
|
||||
}),
|
||||
WherePredicate::RegionPredicate(WhereRegionPredicate {
|
||||
ref lifetime,
|
||||
ref bounds,
|
||||
|
@ -1313,7 +1313,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
hir::TyKind::BareFn(this.arena.alloc(hir::BareFnTy {
|
||||
generic_params: this.lower_generic_params(
|
||||
&f.generic_params,
|
||||
&NodeMap::default(),
|
||||
ImplTraitContext::disallowed(),
|
||||
),
|
||||
unsafety: this.lower_unsafety(f.unsafety),
|
||||
@ -1998,30 +1997,25 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
fn lower_generic_params_mut<'s>(
|
||||
&'s mut self,
|
||||
params: &'s [GenericParam],
|
||||
add_bounds: &'s NodeMap<Vec<GenericBound>>,
|
||||
mut itctx: ImplTraitContext<'s, 'hir>,
|
||||
) -> impl Iterator<Item = hir::GenericParam<'hir>> + Captures<'a> + Captures<'s> {
|
||||
params
|
||||
.iter()
|
||||
.map(move |param| self.lower_generic_param(param, add_bounds, itctx.reborrow()))
|
||||
params.iter().map(move |param| self.lower_generic_param(param, itctx.reborrow()))
|
||||
}
|
||||
|
||||
fn lower_generic_params(
|
||||
&mut self,
|
||||
params: &[GenericParam],
|
||||
add_bounds: &NodeMap<Vec<GenericBound>>,
|
||||
itctx: ImplTraitContext<'_, 'hir>,
|
||||
) -> &'hir [hir::GenericParam<'hir>] {
|
||||
self.arena.alloc_from_iter(self.lower_generic_params_mut(params, add_bounds, itctx))
|
||||
self.arena.alloc_from_iter(self.lower_generic_params_mut(params, itctx))
|
||||
}
|
||||
|
||||
fn lower_generic_param(
|
||||
&mut self,
|
||||
param: &GenericParam,
|
||||
add_bounds: &NodeMap<Vec<GenericBound>>,
|
||||
mut itctx: ImplTraitContext<'_, 'hir>,
|
||||
) -> hir::GenericParam<'hir> {
|
||||
let mut bounds: Vec<_> = self
|
||||
let bounds: Vec<_> = self
|
||||
.with_anonymous_lifetime_mode(AnonymousLifetimeMode::ReportError, |this| {
|
||||
this.lower_param_bounds_mut(¶m.bounds, itctx.reborrow()).collect()
|
||||
});
|
||||
@ -2057,12 +2051,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
(param_name, kind)
|
||||
}
|
||||
GenericParamKind::Type { ref default, .. } => {
|
||||
let add_bounds = add_bounds.get(¶m.id).map_or(&[][..], |x| &x);
|
||||
if !add_bounds.is_empty() {
|
||||
let params = self.lower_param_bounds_mut(add_bounds, itctx.reborrow());
|
||||
bounds.extend(params);
|
||||
}
|
||||
|
||||
let kind = hir::GenericParamKind::Type {
|
||||
default: default.as_ref().map(|x| {
|
||||
self.lower_ty(x, ImplTraitContext::Disallowed(ImplTraitPosition::Other))
|
||||
@ -2123,11 +2111,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
p: &PolyTraitRef,
|
||||
mut itctx: ImplTraitContext<'_, 'hir>,
|
||||
) -> hir::PolyTraitRef<'hir> {
|
||||
let bound_generic_params = self.lower_generic_params(
|
||||
&p.bound_generic_params,
|
||||
&NodeMap::default(),
|
||||
itctx.reborrow(),
|
||||
);
|
||||
let bound_generic_params =
|
||||
self.lower_generic_params(&p.bound_generic_params, itctx.reborrow());
|
||||
|
||||
let trait_ref = self.with_in_scope_lifetime_defs(&p.bound_generic_params, |this| {
|
||||
// Any impl Trait types defined within this scope can capture
|
||||
|
@ -441,10 +441,12 @@ pub enum GenericBound<'hir> {
|
||||
Trait(PolyTraitRef<'hir>, TraitBoundModifier),
|
||||
// FIXME(davidtwco): Introduce `PolyTraitRef::LangItem`
|
||||
LangItemTrait(LangItem, Span, HirId, &'hir GenericArgs<'hir>),
|
||||
Unsized(Span),
|
||||
Outlives(Lifetime),
|
||||
}
|
||||
|
||||
#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
|
||||
rustc_data_structures::static_assert_size!(GenericBound<'_>, 48);
|
||||
|
||||
impl GenericBound<'_> {
|
||||
pub fn trait_ref(&self) -> Option<&TraitRef<'_>> {
|
||||
match self {
|
||||
@ -458,7 +460,6 @@ impl GenericBound<'_> {
|
||||
GenericBound::Trait(t, ..) => t.span,
|
||||
GenericBound::LangItemTrait(_, span, ..) => *span,
|
||||
GenericBound::Outlives(l) => l.span,
|
||||
GenericBound::Unsized(span) => *span,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -871,7 +871,6 @@ pub fn walk_param_bound<'v, V: Visitor<'v>>(visitor: &mut V, bound: &'v GenericB
|
||||
visitor.visit_generic_args(span, args);
|
||||
}
|
||||
GenericBound::Outlives(ref lifetime) => visitor.visit_lifetime(lifetime),
|
||||
GenericBound::Unsized(_) => {}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2232,9 +2232,6 @@ impl<'a> State<'a> {
|
||||
GenericBound::Outlives(lt) => {
|
||||
self.print_lifetime(lt);
|
||||
}
|
||||
GenericBound::Unsized(_) => {
|
||||
self.s.word("?Sized");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,6 @@
|
||||
|
||||
use crate::ty::TyKind::*;
|
||||
use crate::ty::{InferTy, TyCtxt, TyS};
|
||||
use rustc_data_structures::fx::FxHashSet;
|
||||
use rustc_errors::{Applicability, DiagnosticBuilder};
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def_id::DefId;
|
||||
@ -114,10 +113,8 @@ fn suggest_removing_unsized_bound(
|
||||
def_id: Option<DefId>,
|
||||
) {
|
||||
// See if there's a `?Sized` bound that can be removed to suggest that.
|
||||
// First look at the `where` clause because we can have `where T: ?Sized`, but that
|
||||
// `?Sized` bound is *also* included in the `GenericParam` as a bound, which breaks
|
||||
// the spans. Hence the somewhat involved logic that follows.
|
||||
let mut where_unsized_bounds = FxHashSet::default();
|
||||
// First look at the `where` clause because we can have `where T: ?Sized`,
|
||||
// then look at params.
|
||||
for (where_pos, predicate) in generics.where_clause.predicates.iter().enumerate() {
|
||||
match predicate {
|
||||
WherePredicate::BoundPredicate(WhereBoundPredicate {
|
||||
@ -140,7 +137,6 @@ fn suggest_removing_unsized_bound(
|
||||
}) if segment.ident.as_str() == param_name => {
|
||||
for (pos, bound) in bounds.iter().enumerate() {
|
||||
match bound {
|
||||
hir::GenericBound::Unsized(_) => {}
|
||||
hir::GenericBound::Trait(poly, hir::TraitBoundModifier::Maybe)
|
||||
if poly.trait_ref.trait_def_id() == def_id => {}
|
||||
_ => continue,
|
||||
@ -173,7 +169,6 @@ fn suggest_removing_unsized_bound(
|
||||
// ^^^^^^^^^
|
||||
(_, pos, _, _) => bounds[pos - 1].span().shrink_to_hi().to(bound.span()),
|
||||
};
|
||||
where_unsized_bounds.insert(bound.span());
|
||||
err.span_suggestion_verbose(
|
||||
sp,
|
||||
"consider removing the `?Sized` bound to make the \
|
||||
@ -189,8 +184,7 @@ fn suggest_removing_unsized_bound(
|
||||
for (pos, bound) in param.bounds.iter().enumerate() {
|
||||
match bound {
|
||||
hir::GenericBound::Trait(poly, hir::TraitBoundModifier::Maybe)
|
||||
if poly.trait_ref.trait_def_id() == def_id
|
||||
&& !where_unsized_bounds.contains(&bound.span()) =>
|
||||
if poly.trait_ref.trait_def_id() == def_id =>
|
||||
{
|
||||
let sp = match (param.bounds.len(), pos) {
|
||||
// T: ?Sized,
|
||||
|
@ -693,7 +693,6 @@ impl<'tcx> DumpVisitor<'tcx> {
|
||||
(Some(self.tcx.require_lang_item(lang_item, Some(span))), span)
|
||||
}
|
||||
hir::GenericBound::Outlives(..) => continue,
|
||||
hir::GenericBound::Unsized(_) => continue,
|
||||
};
|
||||
|
||||
if let Some(id) = def_id {
|
||||
|
@ -111,11 +111,6 @@ pub trait AstConv<'tcx> {
|
||||
fn record_ty(&self, hir_id: hir::HirId, ty: Ty<'tcx>, span: Span);
|
||||
}
|
||||
|
||||
pub enum SizedByDefault {
|
||||
Yes,
|
||||
No,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct ConvertedBinding<'a, 'tcx> {
|
||||
hir_id: hir::HirId,
|
||||
@ -698,6 +693,61 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
)
|
||||
}
|
||||
|
||||
fn instantiate_poly_trait_ref_inner(
|
||||
&self,
|
||||
hir_id: hir::HirId,
|
||||
span: Span,
|
||||
binding_span: Option<Span>,
|
||||
constness: ty::BoundConstness,
|
||||
bounds: &mut Bounds<'tcx>,
|
||||
speculative: bool,
|
||||
trait_ref_span: Span,
|
||||
trait_def_id: DefId,
|
||||
trait_segment: &hir::PathSegment<'_>,
|
||||
args: &GenericArgs<'_>,
|
||||
infer_args: bool,
|
||||
self_ty: Ty<'tcx>,
|
||||
) -> GenericArgCountResult {
|
||||
let (substs, arg_count) = self.create_substs_for_ast_path(
|
||||
trait_ref_span,
|
||||
trait_def_id,
|
||||
&[],
|
||||
trait_segment,
|
||||
args,
|
||||
infer_args,
|
||||
Some(self_ty),
|
||||
);
|
||||
|
||||
let tcx = self.tcx();
|
||||
let bound_vars = tcx.late_bound_vars(hir_id);
|
||||
debug!(?bound_vars);
|
||||
|
||||
let assoc_bindings = self.create_assoc_bindings_for_generic_args(args);
|
||||
|
||||
let poly_trait_ref =
|
||||
ty::Binder::bind_with_vars(ty::TraitRef::new(trait_def_id, substs), bound_vars);
|
||||
|
||||
debug!(?poly_trait_ref, ?assoc_bindings);
|
||||
bounds.trait_bounds.push((poly_trait_ref, span, constness));
|
||||
|
||||
let mut dup_bindings = FxHashMap::default();
|
||||
for binding in &assoc_bindings {
|
||||
// Specify type to assert that error was already reported in `Err` case.
|
||||
let _: Result<_, ErrorReported> = self.add_predicates_for_ast_type_binding(
|
||||
hir_id,
|
||||
poly_trait_ref,
|
||||
binding,
|
||||
bounds,
|
||||
speculative,
|
||||
&mut dup_bindings,
|
||||
binding_span.unwrap_or(binding.span),
|
||||
);
|
||||
// Okay to ignore `Err` because of `ErrorReported` (see above).
|
||||
}
|
||||
|
||||
arg_count
|
||||
}
|
||||
|
||||
/// Given a trait bound like `Debug`, applies that trait bound the given self-type to construct
|
||||
/// a full trait reference. The resulting trait reference is returned. This may also generate
|
||||
/// auxiliary bounds, which are added to `bounds`.
|
||||
@ -718,7 +768,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
/// `Bar<'a>`. The returned poly-trait-ref will have this binder instantiated explicitly,
|
||||
/// however.
|
||||
#[tracing::instrument(level = "debug", skip(self, span, constness, bounds, speculative))]
|
||||
pub fn instantiate_poly_trait_ref(
|
||||
pub(crate) fn instantiate_poly_trait_ref(
|
||||
&self,
|
||||
trait_ref: &hir::TraitRef<'_>,
|
||||
span: Span,
|
||||
@ -727,48 +777,34 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
bounds: &mut Bounds<'tcx>,
|
||||
speculative: bool,
|
||||
) -> GenericArgCountResult {
|
||||
let hir_id = trait_ref.hir_ref_id;
|
||||
let binding_span = None;
|
||||
let trait_ref_span = trait_ref.path.span;
|
||||
let trait_def_id = trait_ref.trait_def_id().unwrap_or_else(|| FatalError.raise());
|
||||
let trait_segment = trait_ref.path.segments.last().unwrap();
|
||||
let args = trait_segment.args();
|
||||
let infer_args = trait_segment.infer_args;
|
||||
|
||||
self.prohibit_generics(trait_ref.path.segments.split_last().unwrap().1);
|
||||
self.complain_about_internal_fn_trait(span, trait_def_id, trait_segment);
|
||||
|
||||
let tcx = self.tcx();
|
||||
let bound_vars = tcx.late_bound_vars(trait_ref.hir_ref_id);
|
||||
debug!(?bound_vars);
|
||||
|
||||
let (substs, arg_count) = self.create_substs_for_ast_trait_ref(
|
||||
trait_ref.path.span,
|
||||
self.instantiate_poly_trait_ref_inner(
|
||||
hir_id,
|
||||
span,
|
||||
binding_span,
|
||||
constness,
|
||||
bounds,
|
||||
speculative,
|
||||
trait_ref_span,
|
||||
trait_def_id,
|
||||
trait_segment,
|
||||
args,
|
||||
infer_args,
|
||||
self_ty,
|
||||
trait_ref.path.segments.last().unwrap(),
|
||||
);
|
||||
let assoc_bindings = self
|
||||
.create_assoc_bindings_for_generic_args(trait_ref.path.segments.last().unwrap().args());
|
||||
|
||||
let poly_trait_ref =
|
||||
ty::Binder::bind_with_vars(ty::TraitRef::new(trait_def_id, substs), bound_vars);
|
||||
|
||||
debug!(?poly_trait_ref, ?assoc_bindings);
|
||||
bounds.trait_bounds.push((poly_trait_ref, span, constness));
|
||||
|
||||
let mut dup_bindings = FxHashMap::default();
|
||||
for binding in &assoc_bindings {
|
||||
// Specify type to assert that error was already reported in `Err` case.
|
||||
let _: Result<_, ErrorReported> = self.add_predicates_for_ast_type_binding(
|
||||
trait_ref.hir_ref_id,
|
||||
poly_trait_ref,
|
||||
binding,
|
||||
bounds,
|
||||
speculative,
|
||||
&mut dup_bindings,
|
||||
binding.span,
|
||||
);
|
||||
// Okay to ignore `Err` because of `ErrorReported` (see above).
|
||||
}
|
||||
|
||||
arg_count
|
||||
)
|
||||
}
|
||||
|
||||
pub fn instantiate_lang_item_trait_ref(
|
||||
pub(crate) fn instantiate_lang_item_trait_ref(
|
||||
&self,
|
||||
lang_item: hir::LangItem,
|
||||
span: Span,
|
||||
@ -777,36 +813,28 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
self_ty: Ty<'tcx>,
|
||||
bounds: &mut Bounds<'tcx>,
|
||||
) {
|
||||
let binding_span = Some(span);
|
||||
let constness = ty::BoundConstness::NotConst;
|
||||
let speculative = false;
|
||||
let trait_ref_span = span;
|
||||
let trait_def_id = self.tcx().require_lang_item(lang_item, Some(span));
|
||||
let trait_segment = &hir::PathSegment::invalid();
|
||||
let infer_args = false;
|
||||
|
||||
let (substs, _) = self.create_substs_for_ast_path(
|
||||
self.instantiate_poly_trait_ref_inner(
|
||||
hir_id,
|
||||
span,
|
||||
binding_span,
|
||||
constness,
|
||||
bounds,
|
||||
speculative,
|
||||
trait_ref_span,
|
||||
trait_def_id,
|
||||
&[],
|
||||
&hir::PathSegment::invalid(),
|
||||
trait_segment,
|
||||
args,
|
||||
false,
|
||||
Some(self_ty),
|
||||
infer_args,
|
||||
self_ty,
|
||||
);
|
||||
let assoc_bindings = self.create_assoc_bindings_for_generic_args(args);
|
||||
let tcx = self.tcx();
|
||||
let bound_vars = tcx.late_bound_vars(hir_id);
|
||||
let poly_trait_ref =
|
||||
ty::Binder::bind_with_vars(ty::TraitRef::new(trait_def_id, substs), bound_vars);
|
||||
bounds.trait_bounds.push((poly_trait_ref, span, ty::BoundConstness::NotConst));
|
||||
|
||||
let mut dup_bindings = FxHashMap::default();
|
||||
for binding in assoc_bindings {
|
||||
let _: Result<_, ErrorReported> = self.add_predicates_for_ast_type_binding(
|
||||
hir_id,
|
||||
poly_trait_ref,
|
||||
&binding,
|
||||
bounds,
|
||||
false,
|
||||
&mut dup_bindings,
|
||||
span,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
fn ast_path_to_mono_trait_ref(
|
||||
@ -853,46 +881,76 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
.is_some()
|
||||
}
|
||||
|
||||
// Returns `true` if a bounds list includes `?Sized`.
|
||||
pub fn is_unsized(&self, ast_bounds: &[hir::GenericBound<'_>], span: Span) -> bool {
|
||||
// Sets `implicitly_sized` to true on `Bounds` if necessary
|
||||
pub(crate) fn add_implicitly_sized<'hir>(
|
||||
&self,
|
||||
bounds: &mut Bounds<'hir>,
|
||||
ast_bounds: &'hir [hir::GenericBound<'hir>],
|
||||
self_ty_where_predicates: Option<(hir::HirId, &'hir [hir::WherePredicate<'hir>])>,
|
||||
span: Span,
|
||||
) {
|
||||
let tcx = self.tcx();
|
||||
|
||||
// Try to find an unbound in bounds.
|
||||
let mut unbound = None;
|
||||
for ab in ast_bounds {
|
||||
if let hir::GenericBound::Trait(ptr, hir::TraitBoundModifier::Maybe) = ab {
|
||||
if unbound.is_none() {
|
||||
unbound = Some(&ptr.trait_ref);
|
||||
} else {
|
||||
tcx.sess.emit_err(MultipleRelaxedDefaultBounds { span });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let kind_id = tcx.lang_items().require(LangItem::Sized);
|
||||
match unbound {
|
||||
Some(tpb) => {
|
||||
// FIXME(#8559) currently requires the unbound to be built-in.
|
||||
if let Ok(kind_id) = kind_id {
|
||||
if tpb.path.res != Res::Def(DefKind::Trait, kind_id) {
|
||||
tcx.sess.span_warn(
|
||||
span,
|
||||
"default bound relaxed for a type parameter, but \
|
||||
this does nothing because the given bound is not \
|
||||
a default; only `?Sized` is supported",
|
||||
);
|
||||
return false;
|
||||
let mut search_bounds = |ast_bounds: &'hir [hir::GenericBound<'hir>]| {
|
||||
for ab in ast_bounds {
|
||||
if let hir::GenericBound::Trait(ptr, hir::TraitBoundModifier::Maybe) = ab {
|
||||
if unbound.is_none() {
|
||||
unbound = Some(&ptr.trait_ref);
|
||||
} else {
|
||||
tcx.sess.emit_err(MultipleRelaxedDefaultBounds { span });
|
||||
}
|
||||
}
|
||||
}
|
||||
_ if kind_id.is_ok() => {
|
||||
return false;
|
||||
};
|
||||
search_bounds(ast_bounds);
|
||||
if let Some((self_ty, where_clause)) = self_ty_where_predicates {
|
||||
let self_ty_def_id = tcx.hir().local_def_id(self_ty).to_def_id();
|
||||
for clause in where_clause {
|
||||
match clause {
|
||||
hir::WherePredicate::BoundPredicate(pred) => {
|
||||
match pred.bounded_ty.kind {
|
||||
hir::TyKind::Path(hir::QPath::Resolved(_, path)) => match path.res {
|
||||
Res::Def(DefKind::TyParam, def_id) if def_id == self_ty_def_id => {}
|
||||
_ => continue,
|
||||
},
|
||||
_ => continue,
|
||||
}
|
||||
search_bounds(pred.bounds);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
// No lang item for `Sized`, so we can't add it as a bound.
|
||||
None => {}
|
||||
}
|
||||
|
||||
true
|
||||
let sized_def_id = tcx.lang_items().require(LangItem::Sized);
|
||||
match (&sized_def_id, unbound) {
|
||||
(Ok(sized_def_id), Some(tpb))
|
||||
if tpb.path.res == Res::Def(DefKind::Trait, *sized_def_id) =>
|
||||
{
|
||||
// There was in fact a `?Sized` bound, return without doing anything
|
||||
return;
|
||||
}
|
||||
(_, Some(_)) => {
|
||||
// There was a `?Trait` bound, but it was not `?Sized`; warn.
|
||||
tcx.sess.span_warn(
|
||||
span,
|
||||
"default bound relaxed for a type parameter, but \
|
||||
this does nothing because the given bound is not \
|
||||
a default; only `?Sized` is supported",
|
||||
);
|
||||
// Otherwise, add implicitly sized if `Sized` is available.
|
||||
}
|
||||
_ => {
|
||||
// There was no `?Sized` bound; add implicitly sized if `Sized` is available.
|
||||
}
|
||||
}
|
||||
if sized_def_id.is_err() {
|
||||
// No lang item for `Sized`, so we can't add it as a bound.
|
||||
return;
|
||||
}
|
||||
bounds.implicitly_sized = Some(span);
|
||||
}
|
||||
|
||||
/// This helper takes a *converted* parameter type (`param_ty`)
|
||||
@ -910,46 +968,43 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
/// **A note on binders:** there is an implied binder around
|
||||
/// `param_ty` and `ast_bounds`. See `instantiate_poly_trait_ref`
|
||||
/// for more details.
|
||||
#[tracing::instrument(level = "debug", skip(self, bounds))]
|
||||
fn add_bounds(
|
||||
#[tracing::instrument(level = "debug", skip(self, ast_bounds, bounds))]
|
||||
pub(crate) fn add_bounds<'hir, I: Iterator<Item = &'hir hir::GenericBound<'hir>>>(
|
||||
&self,
|
||||
param_ty: Ty<'tcx>,
|
||||
ast_bounds: &[hir::GenericBound<'_>],
|
||||
ast_bounds: I,
|
||||
bounds: &mut Bounds<'tcx>,
|
||||
bound_vars: &'tcx ty::List<ty::BoundVariableKind>,
|
||||
) {
|
||||
for ast_bound in ast_bounds {
|
||||
match *ast_bound {
|
||||
hir::GenericBound::Trait(ref b, hir::TraitBoundModifier::None) => {
|
||||
self.instantiate_poly_trait_ref(
|
||||
&b.trait_ref,
|
||||
b.span,
|
||||
ty::BoundConstness::NotConst,
|
||||
match ast_bound {
|
||||
hir::GenericBound::Trait(poly_trait_ref, modifier) => {
|
||||
let constness = match modifier {
|
||||
hir::TraitBoundModifier::MaybeConst => ty::BoundConstness::ConstIfConst,
|
||||
hir::TraitBoundModifier::None => ty::BoundConstness::NotConst,
|
||||
hir::TraitBoundModifier::Maybe => continue,
|
||||
};
|
||||
|
||||
let _ = self.instantiate_poly_trait_ref(
|
||||
&poly_trait_ref.trait_ref,
|
||||
poly_trait_ref.span,
|
||||
constness,
|
||||
param_ty,
|
||||
bounds,
|
||||
false,
|
||||
);
|
||||
}
|
||||
hir::GenericBound::Trait(ref b, hir::TraitBoundModifier::MaybeConst) => {
|
||||
self.instantiate_poly_trait_ref(
|
||||
&b.trait_ref,
|
||||
b.span,
|
||||
ty::BoundConstness::ConstIfConst,
|
||||
param_ty,
|
||||
bounds,
|
||||
false,
|
||||
);
|
||||
}
|
||||
hir::GenericBound::Trait(_, hir::TraitBoundModifier::Maybe)
|
||||
| hir::GenericBound::Unsized(_) => {}
|
||||
hir::GenericBound::LangItemTrait(lang_item, span, hir_id, args) => self
|
||||
.instantiate_lang_item_trait_ref(
|
||||
&hir::GenericBound::LangItemTrait(lang_item, span, hir_id, args) => {
|
||||
self.instantiate_lang_item_trait_ref(
|
||||
lang_item, span, hir_id, args, param_ty, bounds,
|
||||
),
|
||||
hir::GenericBound::Outlives(ref l) => bounds.region_bounds.push((
|
||||
ty::Binder::bind_with_vars(self.ast_region_to_region(l, None), bound_vars),
|
||||
l.span,
|
||||
)),
|
||||
);
|
||||
}
|
||||
hir::GenericBound::Outlives(lifetime) => {
|
||||
let region = self.ast_region_to_region(lifetime, None);
|
||||
bounds
|
||||
.region_bounds
|
||||
.push((ty::Binder::bind_with_vars(region, bound_vars), lifetime.span));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -970,24 +1025,20 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
/// example above, but is not true in supertrait listings like `trait Foo: Bar + Baz`.
|
||||
///
|
||||
/// `span` should be the declaration size of the parameter.
|
||||
pub fn compute_bounds(
|
||||
pub(crate) fn compute_bounds(
|
||||
&self,
|
||||
param_ty: Ty<'tcx>,
|
||||
ast_bounds: &[hir::GenericBound<'_>],
|
||||
sized_by_default: SizedByDefault,
|
||||
span: Span,
|
||||
) -> Bounds<'tcx> {
|
||||
self.compute_bounds_inner(param_ty, &ast_bounds, sized_by_default, span)
|
||||
self.compute_bounds_inner(param_ty, &ast_bounds)
|
||||
}
|
||||
|
||||
/// Convert the bounds in `ast_bounds` that refer to traits which define an associated type
|
||||
/// named `assoc_name` into ty::Bounds. Ignore the rest.
|
||||
pub fn compute_bounds_that_match_assoc_type(
|
||||
pub(crate) fn compute_bounds_that_match_assoc_type(
|
||||
&self,
|
||||
param_ty: Ty<'tcx>,
|
||||
ast_bounds: &[hir::GenericBound<'_>],
|
||||
sized_by_default: SizedByDefault,
|
||||
span: Span,
|
||||
assoc_name: Ident,
|
||||
) -> Bounds<'tcx> {
|
||||
let mut result = Vec::new();
|
||||
@ -1002,25 +1053,17 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
}
|
||||
}
|
||||
|
||||
self.compute_bounds_inner(param_ty, &result, sized_by_default, span)
|
||||
self.compute_bounds_inner(param_ty, &result)
|
||||
}
|
||||
|
||||
fn compute_bounds_inner(
|
||||
&self,
|
||||
param_ty: Ty<'tcx>,
|
||||
ast_bounds: &[hir::GenericBound<'_>],
|
||||
sized_by_default: SizedByDefault,
|
||||
span: Span,
|
||||
) -> Bounds<'tcx> {
|
||||
let mut bounds = Bounds::default();
|
||||
|
||||
self.add_bounds(param_ty, ast_bounds, &mut bounds, ty::List::empty());
|
||||
|
||||
bounds.implicitly_sized = if let SizedByDefault::Yes = sized_by_default {
|
||||
if !self.is_unsized(ast_bounds, span) { Some(span) } else { None }
|
||||
} else {
|
||||
None
|
||||
};
|
||||
self.add_bounds(param_ty, ast_bounds.iter(), &mut bounds, ty::List::empty());
|
||||
|
||||
bounds
|
||||
}
|
||||
@ -1212,7 +1255,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
// Calling `skip_binder` is okay, because `add_bounds` expects the `param_ty`
|
||||
// parameter to have a skipped binder.
|
||||
let param_ty = tcx.mk_ty(ty::Projection(projection_ty.skip_binder()));
|
||||
self.add_bounds(param_ty, ast_bounds, bounds, candidate.bound_vars());
|
||||
self.add_bounds(param_ty, ast_bounds.iter(), bounds, candidate.bound_vars());
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
|
@ -14,7 +14,7 @@
|
||||
//! At present, however, we do run collection across all items in the
|
||||
//! crate as a kind of pass. This should eventually be factored away.
|
||||
|
||||
use crate::astconv::{AstConv, SizedByDefault};
|
||||
use crate::astconv::AstConv;
|
||||
use crate::bounds::Bounds;
|
||||
use crate::check::intrinsic::intrinsic_operation_unsafety;
|
||||
use crate::constrained_generic_params as cgp;
|
||||
@ -1156,18 +1156,10 @@ fn super_predicates_that_define_assoc_type(
|
||||
&icx,
|
||||
self_param_ty,
|
||||
&bounds,
|
||||
SizedByDefault::No,
|
||||
item.span,
|
||||
assoc_name,
|
||||
)
|
||||
} else {
|
||||
<dyn AstConv<'_>>::compute_bounds(
|
||||
&icx,
|
||||
self_param_ty,
|
||||
&bounds,
|
||||
SizedByDefault::No,
|
||||
item.span,
|
||||
)
|
||||
<dyn AstConv<'_>>::compute_bounds(&icx, self_param_ty, &bounds)
|
||||
};
|
||||
|
||||
let superbounds1 = superbounds1.predicates(tcx, self_param_ty);
|
||||
@ -2176,12 +2168,13 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericP
|
||||
let param_ty = ty::ParamTy::new(index, name).to_ty(tcx);
|
||||
index += 1;
|
||||
|
||||
let sized = SizedByDefault::Yes;
|
||||
let bounds = <dyn AstConv<'_>>::compute_bounds(
|
||||
let mut bounds = <dyn AstConv<'_>>::compute_bounds(&icx, param_ty, ¶m.bounds);
|
||||
// Params are implicitly sized unless a `?Sized` bound is found
|
||||
<dyn AstConv<'_>>::add_implicitly_sized(
|
||||
&icx,
|
||||
param_ty,
|
||||
&mut bounds,
|
||||
¶m.bounds,
|
||||
sized,
|
||||
Some((param.hir_id, ast_generics.where_clause.predicates)),
|
||||
param.span,
|
||||
);
|
||||
predicates.extend(bounds.predicates(tcx, param_ty));
|
||||
@ -2227,64 +2220,15 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericP
|
||||
}
|
||||
}
|
||||
|
||||
for bound in bound_pred.bounds.iter() {
|
||||
match bound {
|
||||
hir::GenericBound::Trait(poly_trait_ref, modifier) => {
|
||||
let constness = match modifier {
|
||||
hir::TraitBoundModifier::None => ty::BoundConstness::NotConst,
|
||||
hir::TraitBoundModifier::MaybeConst => {
|
||||
ty::BoundConstness::ConstIfConst
|
||||
}
|
||||
// We ignore `where T: ?Sized`, it is already part of
|
||||
// type parameter `T`.
|
||||
hir::TraitBoundModifier::Maybe => continue,
|
||||
};
|
||||
|
||||
let mut bounds = Bounds::default();
|
||||
let _ = <dyn AstConv<'_>>::instantiate_poly_trait_ref(
|
||||
&icx,
|
||||
&poly_trait_ref.trait_ref,
|
||||
poly_trait_ref.span,
|
||||
constness,
|
||||
ty,
|
||||
&mut bounds,
|
||||
false,
|
||||
);
|
||||
predicates.extend(bounds.predicates(tcx, ty));
|
||||
}
|
||||
|
||||
&hir::GenericBound::LangItemTrait(lang_item, span, hir_id, args) => {
|
||||
let mut bounds = Bounds::default();
|
||||
<dyn AstConv<'_>>::instantiate_lang_item_trait_ref(
|
||||
&icx,
|
||||
lang_item,
|
||||
span,
|
||||
hir_id,
|
||||
args,
|
||||
ty,
|
||||
&mut bounds,
|
||||
);
|
||||
predicates.extend(bounds.predicates(tcx, ty));
|
||||
}
|
||||
|
||||
hir::GenericBound::Unsized(_) => {}
|
||||
|
||||
hir::GenericBound::Outlives(lifetime) => {
|
||||
let region =
|
||||
<dyn AstConv<'_>>::ast_region_to_region(&icx, lifetime, None);
|
||||
predicates.insert((
|
||||
ty::Binder::bind_with_vars(
|
||||
ty::PredicateKind::TypeOutlives(ty::OutlivesPredicate(
|
||||
ty, region,
|
||||
)),
|
||||
bound_vars,
|
||||
)
|
||||
.to_predicate(tcx),
|
||||
lifetime.span,
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
let mut bounds = Bounds::default();
|
||||
<dyn AstConv<'_>>::add_bounds(
|
||||
&icx,
|
||||
ty,
|
||||
bound_pred.bounds.iter(),
|
||||
&mut bounds,
|
||||
bound_vars,
|
||||
);
|
||||
predicates.extend(bounds.predicates(tcx, ty));
|
||||
}
|
||||
|
||||
hir::WherePredicate::RegionPredicate(region_pred) => {
|
||||
@ -2498,45 +2442,14 @@ fn predicates_from_bound<'tcx>(
|
||||
param_ty: Ty<'tcx>,
|
||||
bound: &'tcx hir::GenericBound<'tcx>,
|
||||
) -> Vec<(ty::Predicate<'tcx>, Span)> {
|
||||
match *bound {
|
||||
hir::GenericBound::Trait(ref tr, modifier) => {
|
||||
let constness = match modifier {
|
||||
hir::TraitBoundModifier::Maybe => return vec![],
|
||||
hir::TraitBoundModifier::MaybeConst => ty::BoundConstness::ConstIfConst,
|
||||
hir::TraitBoundModifier::None => ty::BoundConstness::NotConst,
|
||||
};
|
||||
|
||||
let mut bounds = Bounds::default();
|
||||
let _ = astconv.instantiate_poly_trait_ref(
|
||||
&tr.trait_ref,
|
||||
tr.span,
|
||||
constness,
|
||||
param_ty,
|
||||
&mut bounds,
|
||||
false,
|
||||
);
|
||||
bounds.predicates(astconv.tcx(), param_ty)
|
||||
}
|
||||
hir::GenericBound::LangItemTrait(lang_item, span, hir_id, args) => {
|
||||
let mut bounds = Bounds::default();
|
||||
astconv.instantiate_lang_item_trait_ref(
|
||||
lang_item,
|
||||
span,
|
||||
hir_id,
|
||||
args,
|
||||
param_ty,
|
||||
&mut bounds,
|
||||
);
|
||||
bounds.predicates(astconv.tcx(), param_ty)
|
||||
}
|
||||
hir::GenericBound::Unsized(_) => vec![],
|
||||
hir::GenericBound::Outlives(ref lifetime) => {
|
||||
let region = astconv.ast_region_to_region(lifetime, None);
|
||||
let pred = ty::PredicateKind::TypeOutlives(ty::OutlivesPredicate(param_ty, region))
|
||||
.to_predicate(astconv.tcx());
|
||||
vec![(pred, lifetime.span)]
|
||||
}
|
||||
}
|
||||
let mut bounds = Bounds::default();
|
||||
astconv.add_bounds(
|
||||
param_ty,
|
||||
std::array::IntoIter::new([bound]),
|
||||
&mut bounds,
|
||||
ty::List::empty(),
|
||||
);
|
||||
bounds.predicates(astconv.tcx(), param_ty)
|
||||
}
|
||||
|
||||
fn compute_sig_of_foreign_fn_decl<'tcx>(
|
||||
|
@ -1,5 +1,5 @@
|
||||
use super::ItemCtxt;
|
||||
use crate::astconv::{AstConv, SizedByDefault};
|
||||
use crate::astconv::AstConv;
|
||||
use rustc_hir as hir;
|
||||
use rustc_infer::traits::util;
|
||||
use rustc_middle::ty::subst::InternalSubsts;
|
||||
@ -17,7 +17,7 @@ use rustc_span::Span;
|
||||
fn associated_type_bounds<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
assoc_item_def_id: DefId,
|
||||
bounds: &'tcx [hir::GenericBound<'tcx>],
|
||||
ast_bounds: &'tcx [hir::GenericBound<'tcx>],
|
||||
span: Span,
|
||||
) -> &'tcx [(ty::Predicate<'tcx>, Span)] {
|
||||
let item_ty = tcx.mk_projection(
|
||||
@ -25,13 +25,10 @@ fn associated_type_bounds<'tcx>(
|
||||
InternalSubsts::identity_for_item(tcx, assoc_item_def_id),
|
||||
);
|
||||
|
||||
let bounds = <dyn AstConv<'_>>::compute_bounds(
|
||||
&ItemCtxt::new(tcx, assoc_item_def_id),
|
||||
item_ty,
|
||||
&bounds,
|
||||
SizedByDefault::Yes,
|
||||
span,
|
||||
);
|
||||
let icx = ItemCtxt::new(tcx, assoc_item_def_id);
|
||||
let mut bounds = <dyn AstConv<'_>>::compute_bounds(&icx, item_ty, &ast_bounds);
|
||||
// Associated types are implicitly sized unless a `?Sized` bound is found
|
||||
<dyn AstConv<'_>>::add_implicitly_sized(&icx, &mut bounds, &ast_bounds, None, span);
|
||||
|
||||
let trait_def_id = tcx.associated_item(assoc_item_def_id).container.id();
|
||||
let trait_predicates = tcx.trait_explicit_predicates_and_bounds(trait_def_id.expect_local());
|
||||
@ -59,21 +56,18 @@ fn associated_type_bounds<'tcx>(
|
||||
fn opaque_type_bounds<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
opaque_def_id: DefId,
|
||||
bounds: &'tcx [hir::GenericBound<'tcx>],
|
||||
ast_bounds: &'tcx [hir::GenericBound<'tcx>],
|
||||
span: Span,
|
||||
) -> &'tcx [(ty::Predicate<'tcx>, Span)] {
|
||||
ty::print::with_no_queries(|| {
|
||||
let item_ty =
|
||||
tcx.mk_opaque(opaque_def_id, InternalSubsts::identity_for_item(tcx, opaque_def_id));
|
||||
|
||||
let bounds = <dyn AstConv<'_>>::compute_bounds(
|
||||
&ItemCtxt::new(tcx, opaque_def_id),
|
||||
item_ty,
|
||||
&bounds,
|
||||
SizedByDefault::Yes,
|
||||
span,
|
||||
)
|
||||
.predicates(tcx, item_ty);
|
||||
let icx = ItemCtxt::new(tcx, opaque_def_id);
|
||||
let mut bounds = <dyn AstConv<'_>>::compute_bounds(&icx, item_ty, &ast_bounds);
|
||||
// Opaque types are implicitly sized unless a `?Sized` bound is found
|
||||
<dyn AstConv<'_>>::add_implicitly_sized(&icx, &mut bounds, &ast_bounds, None, span);
|
||||
let bounds = bounds.predicates(tcx, item_ty);
|
||||
|
||||
debug!("opaque_type_bounds({}) = {:?}", tcx.def_path_str(opaque_def_id), bounds);
|
||||
|
||||
|
@ -129,7 +129,6 @@ impl Clean<GenericBound> for hir::GenericBound<'_> {
|
||||
fn clean(&self, cx: &mut DocContext<'_>) -> GenericBound {
|
||||
match *self {
|
||||
hir::GenericBound::Outlives(lt) => GenericBound::Outlives(lt.clean(cx)),
|
||||
hir::GenericBound::Unsized(_) => GenericBound::maybe_sized(cx),
|
||||
hir::GenericBound::LangItemTrait(lang_item, span, _, generic_args) => {
|
||||
let def_id = cx.tcx.require_lang_item(lang_item, Some(span));
|
||||
|
||||
@ -557,19 +556,13 @@ impl Clean<Generics> for hir::Generics<'_> {
|
||||
WherePredicate::BoundPredicate {
|
||||
ty: Generic(ref name), ref mut bounds, ..
|
||||
} => {
|
||||
if let [] | [GenericBound::TraitBound(_, hir::TraitBoundModifier::Maybe)] =
|
||||
&bounds[..]
|
||||
{
|
||||
if bounds.is_empty() {
|
||||
for param in &mut generics.params {
|
||||
match param.kind {
|
||||
GenericParamDefKind::Lifetime { .. } => {}
|
||||
GenericParamDefKind::Type { bounds: ref mut ty_bounds, .. } => {
|
||||
if ¶m.name == name {
|
||||
mem::swap(bounds, ty_bounds);
|
||||
// We now keep track of `?Sized` obligations in the HIR.
|
||||
// If we don't clear `ty_bounds` we end up with
|
||||
// `fn foo<X: ?Sized>(_: X) where X: ?Sized`.
|
||||
ty_bounds.clear();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -6,7 +6,7 @@ LL | impl<R> External for (Q, R) {}
|
||||
|
|
||||
= note: conflicting implementation in crate `complex_impl_support`:
|
||||
- impl<'a, 'b, 'c, T, U, V, W> External for (T, M<'a, 'b, 'c, Box<U>, V, W>)
|
||||
where <U as FnOnce<(T,)>>::Output == V, <V as Iterator>::Item == T, 'b: 'a, T: 'a, U: FnOnce<(T,)>, U: 'static, V: Iterator, V: Clone, W: Add, <W as Add>::Output: Copy;
|
||||
where <U as FnOnce<(T,)>>::Output == V, <V as Iterator>::Item == T, 'b: 'a, T: 'a, U: 'static, U: FnOnce<(T,)>, V: Iterator, V: Clone, W: Add, <W as Add>::Output: Copy;
|
||||
|
||||
error[E0117]: only traits defined in the current crate can be implemented for arbitrary types
|
||||
--> $DIR/complex-impl.rs:9:1
|
||||
|
@ -440,17 +440,6 @@ note: trait defined here, with 1 lifetime parameter: `'a`
|
||||
LL | trait GenericLifetimeAT<'a> {
|
||||
| ^^^^^^^^^^^^^^^^^ --
|
||||
|
||||
error[E0106]: missing lifetime specifier
|
||||
--> $DIR/wrong-number-of-args.rs:169:44
|
||||
|
|
||||
LL | type C = Box<dyn GenericLifetimeAT<(), AssocTy=()>>;
|
||||
| ^ expected named lifetime parameter
|
||||
|
|
||||
help: consider introducing a named lifetime parameter
|
||||
|
|
||||
LL | type C<'a> = Box<dyn GenericLifetimeAT<'a, (), AssocTy=()>>;
|
||||
| ++++ +++
|
||||
|
||||
error[E0107]: this trait takes 0 generic arguments but 1 generic argument was supplied
|
||||
--> $DIR/wrong-number-of-args.rs:169:26
|
||||
|
|
||||
@ -465,6 +454,17 @@ note: trait defined here, with 0 generic parameters
|
||||
LL | trait GenericLifetimeAT<'a> {
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
||||
error[E0106]: missing lifetime specifier
|
||||
--> $DIR/wrong-number-of-args.rs:169:44
|
||||
|
|
||||
LL | type C = Box<dyn GenericLifetimeAT<(), AssocTy=()>>;
|
||||
| ^ expected named lifetime parameter
|
||||
|
|
||||
help: consider introducing a named lifetime parameter
|
||||
|
|
||||
LL | type C<'a> = Box<dyn GenericLifetimeAT<'a, (), AssocTy=()>>;
|
||||
| ++++ +++
|
||||
|
||||
error[E0107]: this trait takes 1 generic argument but 0 generic arguments were supplied
|
||||
--> $DIR/wrong-number-of-args.rs:181:26
|
||||
|
|
||||
@ -525,17 +525,6 @@ help: add missing generic argument
|
||||
LL | type C = Box<dyn GenericTypeAT<'static, A, AssocTy=()>>;
|
||||
| +++
|
||||
|
||||
error[E0106]: missing lifetime specifier
|
||||
--> $DIR/wrong-number-of-args.rs:201:48
|
||||
|
|
||||
LL | type A = Box<dyn GenericLifetimeTypeAT<AssocTy=()>>;
|
||||
| ^ expected named lifetime parameter
|
||||
|
|
||||
help: consider introducing a named lifetime parameter
|
||||
|
|
||||
LL | type A<'a> = Box<dyn GenericLifetimeTypeAT<'a, AssocTy=()>>;
|
||||
| ++++ +++
|
||||
|
||||
error[E0107]: this trait takes 1 generic argument but 0 generic arguments were supplied
|
||||
--> $DIR/wrong-number-of-args.rs:201:26
|
||||
|
|
||||
@ -552,6 +541,17 @@ help: add missing generic argument
|
||||
LL | type A = Box<dyn GenericLifetimeTypeAT<A, AssocTy=()>>;
|
||||
| ++
|
||||
|
||||
error[E0106]: missing lifetime specifier
|
||||
--> $DIR/wrong-number-of-args.rs:201:48
|
||||
|
|
||||
LL | type A = Box<dyn GenericLifetimeTypeAT<AssocTy=()>>;
|
||||
| ^ expected named lifetime parameter
|
||||
|
|
||||
help: consider introducing a named lifetime parameter
|
||||
|
|
||||
LL | type A<'a> = Box<dyn GenericLifetimeTypeAT<'a, AssocTy=()>>;
|
||||
| ++++ +++
|
||||
|
||||
error[E0107]: this trait takes 1 generic argument but 0 generic arguments were supplied
|
||||
--> $DIR/wrong-number-of-args.rs:207:26
|
||||
|
|
||||
@ -609,17 +609,6 @@ help: consider introducing a named lifetime parameter
|
||||
LL | type D<'a> = Box<dyn GenericLifetimeTypeAT<'a, (), AssocTy=()>>;
|
||||
| ++++ +++
|
||||
|
||||
error[E0106]: missing lifetime specifier
|
||||
--> $DIR/wrong-number-of-args.rs:221:48
|
||||
|
|
||||
LL | type E = Box<dyn GenericLifetimeTypeAT<(), (), AssocTy=()>>;
|
||||
| ^ expected named lifetime parameter
|
||||
|
|
||||
help: consider introducing a named lifetime parameter
|
||||
|
|
||||
LL | type E<'a> = Box<dyn GenericLifetimeTypeAT<'a, (), (), AssocTy=()>>;
|
||||
| ++++ +++
|
||||
|
||||
error[E0107]: this trait takes 1 generic argument but 2 generic arguments were supplied
|
||||
--> $DIR/wrong-number-of-args.rs:221:26
|
||||
|
|
||||
@ -634,6 +623,17 @@ note: trait defined here, with 1 generic parameter: `A`
|
||||
LL | trait GenericLifetimeTypeAT<'a, A> {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^ -
|
||||
|
||||
error[E0106]: missing lifetime specifier
|
||||
--> $DIR/wrong-number-of-args.rs:221:48
|
||||
|
|
||||
LL | type E = Box<dyn GenericLifetimeTypeAT<(), (), AssocTy=()>>;
|
||||
| ^ expected named lifetime parameter
|
||||
|
|
||||
help: consider introducing a named lifetime parameter
|
||||
|
|
||||
LL | type E<'a> = Box<dyn GenericLifetimeTypeAT<'a, (), (), AssocTy=()>>;
|
||||
| ++++ +++
|
||||
|
||||
error[E0107]: this trait takes 1 lifetime argument but 2 lifetime arguments were supplied
|
||||
--> $DIR/wrong-number-of-args.rs:227:26
|
||||
|
|
||||
@ -767,17 +767,6 @@ help: add missing lifetime argument
|
||||
LL | type B = Box<dyn GenericLifetimeLifetimeAT<'static, 'b, AssocTy=()>>;
|
||||
| ++++
|
||||
|
||||
error[E0106]: missing lifetime specifiers
|
||||
--> $DIR/wrong-number-of-args.rs:279:56
|
||||
|
|
||||
LL | type A = Box<dyn GenericLifetimeLifetimeTypeAT<AssocTy=()>>;
|
||||
| ^ expected 2 lifetime parameters
|
||||
|
|
||||
help: consider introducing a named lifetime parameter
|
||||
|
|
||||
LL | type A<'a> = Box<dyn GenericLifetimeLifetimeTypeAT<'a, 'a, AssocTy=()>>;
|
||||
| ++++ +++++++
|
||||
|
||||
error[E0107]: this trait takes 1 generic argument but 0 generic arguments were supplied
|
||||
--> $DIR/wrong-number-of-args.rs:279:26
|
||||
|
|
||||
@ -794,6 +783,17 @@ help: add missing generic argument
|
||||
LL | type A = Box<dyn GenericLifetimeLifetimeTypeAT<A, AssocTy=()>>;
|
||||
| ++
|
||||
|
||||
error[E0106]: missing lifetime specifiers
|
||||
--> $DIR/wrong-number-of-args.rs:279:56
|
||||
|
|
||||
LL | type A = Box<dyn GenericLifetimeLifetimeTypeAT<AssocTy=()>>;
|
||||
| ^ expected 2 lifetime parameters
|
||||
|
|
||||
help: consider introducing a named lifetime parameter
|
||||
|
|
||||
LL | type A<'a> = Box<dyn GenericLifetimeLifetimeTypeAT<'a, 'a, AssocTy=()>>;
|
||||
| ++++ +++++++
|
||||
|
||||
error[E0107]: this trait takes 2 lifetime arguments but 1 lifetime argument was supplied
|
||||
--> $DIR/wrong-number-of-args.rs:285:26
|
||||
|
|
||||
|
@ -11,6 +11,7 @@ trait Trait<'a> {}
|
||||
|
||||
struct S4<T>(T) where for<'a> T: ?Trait<'a>;
|
||||
//~^ ERROR `?Trait` bounds are only permitted at the point where a type parameter is declared
|
||||
//~| WARN default bound relaxed for a type parameter
|
||||
|
||||
struct S5<T>(*const T) where T: ?Trait<'static> + ?Sized;
|
||||
//~^ ERROR type parameter has more than one relaxed default bound
|
||||
|
@ -23,23 +23,29 @@ LL | struct S4<T>(T) where for<'a> T: ?Trait<'a>;
|
||||
| ^
|
||||
|
||||
error: `?Trait` bounds are only permitted at the point where a type parameter is declared
|
||||
--> $DIR/maybe-bounds-where.rs:20:18
|
||||
--> $DIR/maybe-bounds-where.rs:21:18
|
||||
|
|
||||
LL | fn f() where T: ?Sized {}
|
||||
| ^
|
||||
|
||||
warning: default bound relaxed for a type parameter, but this does nothing because the given bound is not a default; only `?Sized` is supported
|
||||
--> $DIR/maybe-bounds-where.rs:12:11
|
||||
|
|
||||
LL | struct S4<T>(T) where for<'a> T: ?Trait<'a>;
|
||||
| ^
|
||||
|
||||
error[E0203]: type parameter has more than one relaxed default bound, only one is supported
|
||||
--> $DIR/maybe-bounds-where.rs:15:11
|
||||
--> $DIR/maybe-bounds-where.rs:16:11
|
||||
|
|
||||
LL | struct S5<T>(*const T) where T: ?Trait<'static> + ?Sized;
|
||||
| ^
|
||||
|
||||
warning: default bound relaxed for a type parameter, but this does nothing because the given bound is not a default; only `?Sized` is supported
|
||||
--> $DIR/maybe-bounds-where.rs:15:11
|
||||
--> $DIR/maybe-bounds-where.rs:16:11
|
||||
|
|
||||
LL | struct S5<T>(*const T) where T: ?Trait<'static> + ?Sized;
|
||||
| ^
|
||||
|
||||
error: aborting due to 6 previous errors; 1 warning emitted
|
||||
error: aborting due to 6 previous errors; 2 warnings emitted
|
||||
|
||||
For more information about this error, try `rustc --explain E0203`.
|
||||
|
Loading…
Reference in New Issue
Block a user