Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 743d2e5

Browse files
committedFeb 27, 2024·
add polarity
1 parent 9afdb8d commit 743d2e5

File tree

34 files changed

+217
-100
lines changed

34 files changed

+217
-100
lines changed
 

‎compiler/rustc_ast_lowering/src/lib.rs

+13-15
Original file line numberDiff line numberDiff line change
@@ -1255,6 +1255,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
12551255
itctx,
12561256
TraitBoundModifiers::NONE,
12571257
);
1258+
let bound = (bound, hir::TraitBoundModifier::None);
12581259
let bounds = this.arena.alloc_from_iter([bound]);
12591260
let lifetime_bound = this.elided_dyn_bound(t.span);
12601261
(bounds, lifetime_bound)
@@ -1386,21 +1387,17 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
13861387
// We can safely ignore constness here since AST validation
13871388
// takes care of rejecting invalid modifier combinations and
13881389
// const trait bounds in trait object types.
1389-
GenericBound::Trait(ty, modifiers) => match modifiers.polarity {
1390-
BoundPolarity::Positive | BoundPolarity::Negative(_) => {
1391-
Some(this.lower_poly_trait_ref(
1392-
ty,
1393-
itctx,
1394-
// Still, don't pass along the constness here; we don't want to
1395-
// synthesize any host effect args, it'd only cause problems.
1396-
TraitBoundModifiers {
1397-
constness: BoundConstness::Never,
1398-
..*modifiers
1399-
},
1400-
))
1401-
}
1402-
BoundPolarity::Maybe(_) => None,
1403-
},
1390+
GenericBound::Trait(ty, modifiers) => {
1391+
// Still, don't pass along the constness here; we don't want to
1392+
// synthesize any host effect args, it'd only cause problems.
1393+
let modifiers = TraitBoundModifiers {
1394+
constness: BoundConstness::Never,
1395+
..*modifiers
1396+
};
1397+
let trait_ref = this.lower_poly_trait_ref(ty, itctx, modifiers);
1398+
let polarity = this.lower_trait_bound_modifiers(modifiers);
1399+
Some((trait_ref, polarity))
1400+
}
14041401
GenericBound::Outlives(lifetime) => {
14051402
if lifetime_bound.is_none() {
14061403
lifetime_bound = Some(this.lower_lifetime(lifetime));
@@ -2502,6 +2499,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
25022499
trait_ref: hir::TraitRef { path, hir_ref_id: hir_id },
25032500
span: self.lower_span(span),
25042501
};
2502+
let principal = (principal, hir::TraitBoundModifier::None);
25052503

25062504
// The original ID is taken by the `PolyTraitRef`,
25072505
// so the `Ty` itself needs a different one.

‎compiler/rustc_ast_passes/messages.ftl

-5
Original file line numberDiff line numberDiff line change
@@ -202,11 +202,6 @@ ast_passes_nomangle_ascii = `#[no_mangle]` requires ASCII identifier
202202
ast_passes_obsolete_auto = `impl Trait for .. {"{}"}` is an obsolete syntax
203203
.help = use `auto trait Trait {"{}"}` instead
204204
205-
ast_passes_optional_trait_object = `?Trait` is not permitted in trait object types
206-
207-
ast_passes_optional_trait_supertrait = `?Trait` is not permitted in supertraits
208-
.note = traits are `?{$path_str}` by default
209-
210205
ast_passes_out_of_order_params = {$param_ord} parameters must be declared prior to {$max_param} parameters
211206
.suggestion = reorder the parameters: lifetimes, then consts and types
212207

‎compiler/rustc_ast_passes/src/ast_validation.rs

+1-9
Original file line numberDiff line numberDiff line change
@@ -1260,16 +1260,8 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
12601260

12611261
fn visit_param_bound(&mut self, bound: &'a GenericBound, ctxt: BoundKind) {
12621262
if let GenericBound::Trait(poly, modifiers) = bound {
1263+
// Some of the arms are feature-gated. See `feature_gate::PostExpansionVisitor`.
12631264
match (ctxt, modifiers.constness, modifiers.polarity) {
1264-
(BoundKind::SuperTraits, BoundConstness::Never, BoundPolarity::Maybe(_)) => {
1265-
self.dcx().emit_err(errors::OptionalTraitSupertrait {
1266-
span: poly.span,
1267-
path_str: pprust::path_to_string(&poly.trait_ref.path),
1268-
});
1269-
}
1270-
(BoundKind::TraitObject, BoundConstness::Never, BoundPolarity::Maybe(_)) => {
1271-
self.dcx().emit_err(errors::OptionalTraitObject { span: poly.span });
1272-
}
12731265
(BoundKind::TraitObject, BoundConstness::Always(_), BoundPolarity::Positive) => {
12741266
self.dcx().emit_err(errors::ConstBoundTraitObject { span: poly.span });
12751267
}

‎compiler/rustc_ast_passes/src/errors.rs

-16
Original file line numberDiff line numberDiff line change
@@ -543,22 +543,6 @@ pub struct NestedLifetimes {
543543
pub span: Span,
544544
}
545545

546-
#[derive(Diagnostic)]
547-
#[diag(ast_passes_optional_trait_supertrait)]
548-
#[note]
549-
pub struct OptionalTraitSupertrait {
550-
#[primary_span]
551-
pub span: Span,
552-
pub path_str: String,
553-
}
554-
555-
#[derive(Diagnostic)]
556-
#[diag(ast_passes_optional_trait_object)]
557-
pub struct OptionalTraitObject {
558-
#[primary_span]
559-
pub span: Span,
560-
}
561-
562546
#[derive(Diagnostic)]
563547
#[diag(ast_passes_const_bound_trait_object)]
564548
pub struct ConstBoundTraitObject {

‎compiler/rustc_ast_passes/src/feature_gate.rs

+21
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,27 @@ impl<'a> PostExpansionVisitor<'a> {
169169
}
170170

171171
impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
172+
fn visit_param_bound(&mut self, bound: &'a ast::GenericBound, ctxt: visit::BoundKind) {
173+
use ast::visit::BoundKind;
174+
use ast::{BoundConstness, BoundPolarity};
175+
if let ast::GenericBound::Trait(poly, modifiers) = bound {
176+
let gate = |descr| {
177+
gate!(&self, allow_maybe_polarity, poly.span, descr);
178+
};
179+
180+
match (ctxt, modifiers.constness, modifiers.polarity) {
181+
(BoundKind::TraitObject, BoundConstness::Never, BoundPolarity::Maybe(_)) => {
182+
gate("`?Trait` is not permitted in trait object types");
183+
}
184+
(BoundKind::SuperTraits, BoundConstness::Never, BoundPolarity::Maybe(_)) => {
185+
gate("`?Trait` is not permitted in supertraits");
186+
}
187+
_ => {}
188+
}
189+
}
190+
visit::walk_param_bound(self, bound);
191+
}
192+
172193
fn visit_attribute(&mut self, attr: &ast::Attribute) {
173194
let attr_info = attr.ident().and_then(|ident| BUILTIN_ATTRIBUTE_MAP.get(&ident.name));
174195
// Check feature gates for built-in attributes.

‎compiler/rustc_feature/src/unstable.rs

+2
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,8 @@ declare_features! (
191191
/// below (it has to be checked before expansion possibly makes
192192
/// macros disappear).
193193
(internal, allow_internal_unstable, "1.0.0", None),
194+
/// Allows using `?Trait` trait bound.
195+
(internal, allow_maybe_polarity, "CURRENT_RUSTC_VERSION", None),
194196
/// Allows using anonymous lifetimes in argument-position impl-trait.
195197
(unstable, anonymous_lifetime_in_impl_trait, "1.63.0", None),
196198
/// Allows identifying the `compiler_builtins` crate.

‎compiler/rustc_hir/src/hir.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -2603,7 +2603,11 @@ pub enum TyKind<'hir> {
26032603
OpaqueDef(ItemId, &'hir [GenericArg<'hir>], bool),
26042604
/// A trait object type `Bound1 + Bound2 + Bound3`
26052605
/// where `Bound` is a trait or a lifetime.
2606-
TraitObject(&'hir [PolyTraitRef<'hir>], &'hir Lifetime, TraitObjectSyntax),
2606+
TraitObject(
2607+
&'hir [(PolyTraitRef<'hir>, TraitBoundModifier)],
2608+
&'hir Lifetime,
2609+
TraitObjectSyntax,
2610+
),
26072611
/// Unused for now.
26082612
Typeof(AnonConst),
26092613
/// `TyKind::Infer` means the type should be inferred instead of it having been

‎compiler/rustc_hir/src/intravisit.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -873,7 +873,9 @@ pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty<'v>) -> V::Resul
873873
try_visit!(visitor.visit_array_length(length));
874874
}
875875
TyKind::TraitObject(bounds, ref lifetime, _syntax) => {
876-
walk_list!(visitor, visit_poly_trait_ref, bounds);
876+
for (bound, _) in bounds {
877+
try_visit!(visitor.visit_poly_trait_ref(bound));
878+
}
877879
try_visit!(visitor.visit_lifetime(lifetime));
878880
}
879881
TyKind::Typeof(ref expression) => try_visit!(visitor.visit_anon_const(expression)),

‎compiler/rustc_hir_analysis/src/astconv/bounds.rs

+8-6
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
6666
}
6767
}
6868

69-
if unbounds.len() > 1 {
69+
if unbounds.len() > 1 && !tcx.features().allow_maybe_polarity {
7070
tcx.dcx().emit_err(errors::MultipleRelaxedDefaultBounds {
7171
spans: unbounds.iter().map(|ptr| ptr.span).collect(),
7272
});
@@ -80,12 +80,14 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
8080
seen_sized_unbound = true;
8181
continue;
8282
}
83-
// There was a `?Trait` bound, but it was not `?Sized`; warn.
84-
tcx.dcx().span_warn(
85-
unbound.span,
86-
"relaxing a default bound only does something for `?Sized`; \
83+
if !tcx.features().allow_maybe_polarity {
84+
// There was a `?Trait` bound, but it was not `?Sized`; warn.
85+
tcx.dcx().span_warn(
86+
unbound.span,
87+
"relaxing a default bound only does something for `?Sized`; \
8788
all other traits are not bound by default",
88-
);
89+
);
90+
}
8991
}
9092

9193
if seen_sized_unbound || seen_negative_sized_bound || seen_positive_sized_bound {

‎compiler/rustc_hir_analysis/src/astconv/errors.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -592,7 +592,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
592592
&self,
593593
associated_types: FxIndexMap<Span, FxIndexSet<DefId>>,
594594
potential_assoc_types: Vec<Span>,
595-
trait_bounds: &[hir::PolyTraitRef<'_>],
595+
trait_bounds: &[(hir::PolyTraitRef<'_>, hir::TraitBoundModifier)],
596596
) {
597597
if associated_types.values().all(|v| v.is_empty()) {
598598
return;
@@ -634,7 +634,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
634634
if object_safety_violations {
635635
return;
636636
}
637-
if let ([], [bound]) = (&potential_assoc_types[..], &trait_bounds) {
637+
if let ([], [(bound, _)]) = (&potential_assoc_types[..], &trait_bounds) {
638638
match bound.trait_ref.path.segments {
639639
// FIXME: `trait_ref.path.span` can point to a full path with multiple
640640
// segments, even though `trait_ref.path.segments` is of length `1`. Work
@@ -676,7 +676,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
676676
// and we can then use their span to indicate this to the user.
677677
let bound_names = trait_bounds
678678
.iter()
679-
.filter_map(|poly_trait_ref| {
679+
.filter_map(|(poly_trait_ref, _)| {
680680
let path = poly_trait_ref.trait_ref.path.segments.last()?;
681681
let args = path.args?;
682682

‎compiler/rustc_hir_analysis/src/astconv/lint.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
101101
let mut is_downgradable = true;
102102
let is_object_safe = match self_ty.kind {
103103
hir::TyKind::TraitObject(objects, ..) => {
104-
objects.iter().all(|o| match o.trait_ref.path.res {
104+
objects.iter().all(|(o, _)| match o.trait_ref.path.res {
105105
Res::Def(DefKind::Trait, id) => {
106106
if Some(id) == owner {
107107
// For recursive traits, don't downgrade the error. (#119652)
@@ -192,7 +192,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
192192

193193
pub(super) fn maybe_lint_bare_trait(&self, self_ty: &hir::Ty<'_>, in_path: bool) {
194194
let tcx = self.tcx();
195-
if let hir::TyKind::TraitObject([poly_trait_ref, ..], _, TraitObjectSyntax::None) =
195+
if let hir::TyKind::TraitObject([(poly_trait_ref, _), ..], _, TraitObjectSyntax::None) =
196196
self_ty.kind
197197
{
198198
let needs_bracket = in_path

‎compiler/rustc_hir_analysis/src/astconv/object_safety.rs

+6-3
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
2222
&self,
2323
span: Span,
2424
hir_id: hir::HirId,
25-
hir_trait_bounds: &[hir::PolyTraitRef<'tcx>],
25+
hir_trait_bounds: &[(hir::PolyTraitRef<'tcx>, hir::TraitBoundModifier)],
2626
lifetime: &hir::Lifetime,
2727
borrowed: bool,
2828
representation: DynKind,
@@ -32,7 +32,10 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
3232
let mut bounds = Bounds::default();
3333
let mut potential_assoc_types = Vec::new();
3434
let dummy_self = self.tcx().types.trait_object_dummy_self;
35-
for trait_bound in hir_trait_bounds.iter().rev() {
35+
for (trait_bound, modifier) in hir_trait_bounds.iter().rev() {
36+
if *modifier == hir::TraitBoundModifier::Maybe {
37+
continue;
38+
}
3639
if let GenericArgCountResult {
3740
correct:
3841
Err(GenericArgCountMismatch { invalid_args: cur_potential_assoc_types, .. }),
@@ -279,7 +282,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
279282
let args = tcx.mk_args(&args);
280283

281284
let span = i.bottom().1;
282-
let empty_generic_args = hir_trait_bounds.iter().any(|hir_bound| {
285+
let empty_generic_args = hir_trait_bounds.iter().any(|(hir_bound, _)| {
283286
hir_bound.trait_ref.path.res == Res::Def(DefKind::Trait, trait_ref.def_id)
284287
&& hir_bound.span.contains(span)
285288
});

‎compiler/rustc_hir_analysis/src/check/wfcheck.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -834,7 +834,7 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for GATArgsCollector<'tcx> {
834834

835835
fn could_be_self(trait_def_id: LocalDefId, ty: &hir::Ty<'_>) -> bool {
836836
match ty.kind {
837-
hir::TyKind::TraitObject([trait_ref], ..) => match trait_ref.trait_ref.path.segments {
837+
hir::TyKind::TraitObject([(trait_ref, _)], ..) => match trait_ref.trait_ref.path.segments {
838838
[s] => s.res.opt_def_id() == Some(trait_def_id.to_def_id()),
839839
_ => false,
840840
},

‎compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -638,7 +638,10 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
638638
debug!(?bounds, ?lifetime, "TraitObject");
639639
let scope = Scope::TraitRefBoundary { s: self.scope };
640640
self.with(scope, |this| {
641-
for bound in bounds {
641+
for (bound, modifier) in bounds {
642+
if *modifier == hir::TraitBoundModifier::Maybe {
643+
continue;
644+
}
642645
this.visit_poly_trait_ref_inner(
643646
bound,
644647
NonLifetimeBinderAllowed::Deny("trait object types"),

‎compiler/rustc_hir_pretty/src/lib.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -293,13 +293,16 @@ impl<'a> State<'a> {
293293
self.word_space("dyn");
294294
}
295295
let mut first = true;
296-
for bound in bounds {
296+
for (bound, modifier) in bounds {
297297
if first {
298298
first = false;
299299
} else {
300300
self.nbsp();
301301
self.word_space("+");
302302
}
303+
if *modifier == TraitBoundModifier::Maybe {
304+
self.word("?");
305+
}
303306
self.print_poly_trait_ref(bound);
304307
}
305308
if !lifetime.is_elided() {

‎compiler/rustc_infer/src/infer/error_reporting/nice_region_error/find_anon_type.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ impl<'tcx> Visitor<'tcx> for FindNestedTypeVisitor<'tcx> {
8888
}
8989

9090
hir::TyKind::TraitObject(bounds, ..) => {
91-
for bound in bounds {
91+
for (bound, _) in bounds {
9292
self.current_index.shift_in(1);
9393
self.visit_poly_trait_ref(bound);
9494
self.current_index.shift_out(1);

‎compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -569,7 +569,7 @@ impl<'a, 'tcx> Visitor<'tcx> for HirTraitObjectVisitor<'a> {
569569
_,
570570
) = t.kind
571571
{
572-
for ptr in poly_trait_refs {
572+
for (ptr, _) in poly_trait_refs {
573573
if Some(self.1) == ptr.trait_ref.trait_def_id() {
574574
self.0.push(ptr.span);
575575
}

‎compiler/rustc_infer/src/traits/error_reporting/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ pub fn report_object_safety_error<'tcx>(
6262

6363
if let Some(hir_id) = hir_id
6464
&& let hir::Node::Ty(ty) = tcx.hir_node(hir_id)
65-
&& let hir::TyKind::TraitObject([trait_ref, ..], ..) = ty.kind
65+
&& let hir::TyKind::TraitObject([(trait_ref, _), ..], ..) = ty.kind
6666
{
6767
let mut hir_id = hir_id;
6868
while let hir::Node::Ty(ty) = tcx.parent_hir_node(hir_id) {

‎compiler/rustc_lint/src/non_local_def.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ impl<'tcx> LateLintPass<'tcx> for NonLocalDefinitions {
127127
TyKind::Path(QPath::Resolved(_, ty_path)) => {
128128
path_has_local_parent(ty_path, cx, &*local_parents)
129129
}
130-
TyKind::TraitObject([principle_poly_trait_ref, ..], _, _) => {
130+
TyKind::TraitObject([(principle_poly_trait_ref, _), ..], _, _) => {
131131
path_has_local_parent(
132132
principle_poly_trait_ref.trait_ref.path,
133133
cx,

‎compiler/rustc_lint/src/traits.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -112,9 +112,11 @@ impl<'tcx> LateLintPass<'tcx> for DropTraitConstraints {
112112

113113
fn check_ty(&mut self, cx: &LateContext<'_>, ty: &'tcx hir::Ty<'tcx>) {
114114
let hir::TyKind::TraitObject(bounds, _lifetime, _syntax) = &ty.kind else { return };
115-
for bound in &bounds[..] {
115+
for (bound, modifier) in &bounds[..] {
116116
let def_id = bound.trait_ref.trait_def_id();
117-
if cx.tcx.lang_items().drop_trait() == def_id {
117+
if cx.tcx.lang_items().drop_trait() == def_id
118+
&& *modifier != hir::TraitBoundModifier::Maybe
119+
{
118120
let Some(def_id) = cx.tcx.get_diagnostic_item(sym::needs_drop) else { return };
119121
cx.emit_span_lint(DYN_DROP, bound.span, DropGlue { tcx: cx.tcx, def_id });
120122
}

‎compiler/rustc_span/src/symbol.rs

+1
Original file line numberDiff line numberDiff line change
@@ -377,6 +377,7 @@ symbols! {
377377
allow_fail,
378378
allow_internal_unsafe,
379379
allow_internal_unstable,
380+
allow_maybe_polarity,
380381
alu32,
381382
always,
382383
and,

‎compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -2994,11 +2994,11 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
29942994
match ty.kind {
29952995
hir::TyKind::TraitObject(traits, _, _) => {
29962996
let (span, kw) = match traits {
2997-
[first, ..] if first.span.lo() == ty.span.lo() => {
2997+
[(first, _), ..] if first.span.lo() == ty.span.lo() => {
29982998
// Missing `dyn` in front of trait object.
29992999
(ty.span.shrink_to_lo(), "dyn ")
30003000
}
3001-
[first, ..] => (ty.span.until(first.span), ""),
3001+
[(first, _), ..] => (ty.span.until(first.span), ""),
30023002
[] => span_bug!(ty.span, "trait object with no traits: {ty:?}"),
30033003
};
30043004
let needs_parens = traits.len() != 1;

‎src/librustdoc/clean/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1859,7 +1859,7 @@ pub(crate) fn clean_ty<'tcx>(ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> T
18591859
}
18601860
TyKind::Path(_) => clean_qpath(ty, cx),
18611861
TyKind::TraitObject(bounds, ref lifetime, _) => {
1862-
let bounds = bounds.iter().map(|bound| clean_poly_trait_ref(bound, cx)).collect();
1862+
let bounds = bounds.iter().map(|(bound, _)| clean_poly_trait_ref(bound, cx)).collect();
18631863
let lifetime =
18641864
if !lifetime.is_elided() { Some(clean_lifetime(*lifetime, cx)) } else { None };
18651865
DynTrait(bounds, lifetime)

‎src/tools/clippy/clippy_lints/src/lifetimes.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -549,7 +549,7 @@ impl<'a, 'tcx> Visitor<'tcx> for RefVisitor<'a, 'tcx> {
549549
if !lt.is_elided() {
550550
self.unelided_trait_object_lifetime = true;
551551
}
552-
for bound in bounds {
552+
for (bound, _) in bounds {
553553
self.visit_poly_trait_ref(bound);
554554
}
555555
},

‎src/tools/clippy/clippy_lints/src/trait_bounds.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ impl<'tcx> LateLintPass<'tcx> for TraitBounds {
181181

182182
// Iterate the bounds and add them to our seen hash
183183
// If we haven't yet seen it, add it to the fixed traits
184-
for bound in bounds {
184+
for (bound, _) in bounds {
185185
let Some(def_id) = bound.trait_ref.trait_def_id() else {
186186
continue;
187187
};
@@ -196,9 +196,9 @@ impl<'tcx> LateLintPass<'tcx> for TraitBounds {
196196
// If the number of unique traits isn't the same as the number of traits in the bounds,
197197
// there must be 1 or more duplicates
198198
if bounds.len() != unique_traits.len() {
199-
let mut bounds_span = bounds[0].span;
199+
let mut bounds_span = bounds[0].0.span;
200200

201-
for bound in bounds.iter().skip(1) {
201+
for (bound, _) in bounds.iter().skip(1) {
202202
bounds_span = bounds_span.to(bound.span);
203203
}
204204

‎src/tools/clippy/clippy_lints/src/types/borrowed_box.rs

+12-8
Original file line numberDiff line numberDiff line change
@@ -81,14 +81,18 @@ pub(super) fn check(cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>, lt: &Lifetime, m
8181

8282
// Returns true if given type is `Any` trait.
8383
fn is_any_trait(cx: &LateContext<'_>, t: &hir::Ty<'_>) -> bool {
84-
if let TyKind::TraitObject(traits, ..) = t.kind
85-
&& !traits.is_empty()
86-
&& let Some(trait_did) = traits[0].trait_ref.trait_def_id()
87-
// Only Send/Sync can be used as additional traits, so it is enough to
88-
// check only the first trait.
89-
&& cx.tcx.is_diagnostic_item(sym::Any, trait_did)
90-
{
91-
return true;
84+
if let TyKind::TraitObject(traits, ..) = t.kind {
85+
return traits
86+
.iter()
87+
.find(|(bound, _)| {
88+
if let Some(trait_did) = bound.trait_ref.trait_def_id()
89+
&& cx.tcx.is_diagnostic_item(sym::Any, trait_did)
90+
{
91+
return true;
92+
}
93+
false
94+
})
95+
.is_some();
9296
}
9397

9498
false

‎src/tools/clippy/clippy_lints/src/types/type_complexity.rs

+1
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ impl<'tcx> Visitor<'tcx> for TypeComplexityVisitor {
5555
TyKind::TraitObject(param_bounds, _, _) => {
5656
let has_lifetime_parameters = param_bounds.iter().any(|bound| {
5757
bound
58+
.0
5859
.bound_generic_params
5960
.iter()
6061
.any(|gen| matches!(gen.kind, GenericParamKind::Lifetime { .. }))
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#![feature(auto_traits)]
2+
3+
trait Trait1 {}
4+
auto trait Trait2 {}
5+
trait Trait3: ?Trait1 {}
6+
//~^ ERROR `?Trait` is not permitted in supertraits
7+
8+
fn foo(_: Box<dyn Trait1 + ?Trait2>) {}
9+
//~^ ERROR `?Trait` is not permitted in trait object types
10+
fn bar<T: ?Trait1>(_: T) {}
11+
//~^ WARN relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
12+
13+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
error[E0658]: `?Trait` is not permitted in supertraits
2+
--> $DIR/feature-gate-allow-maybe-polarity.rs:5:15
3+
|
4+
LL | trait Trait3: ?Trait1 {}
5+
| ^^^^^^^
6+
|
7+
= help: add `#![feature(allow_maybe_polarity)]` to the crate attributes to enable
8+
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
9+
10+
error[E0658]: `?Trait` is not permitted in trait object types
11+
--> $DIR/feature-gate-allow-maybe-polarity.rs:8:28
12+
|
13+
LL | fn foo(_: Box<dyn Trait1 + ?Trait2>) {}
14+
| ^^^^^^^
15+
|
16+
= help: add `#![feature(allow_maybe_polarity)]` to the crate attributes to enable
17+
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
18+
19+
warning: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
20+
--> $DIR/feature-gate-allow-maybe-polarity.rs:10:11
21+
|
22+
LL | fn bar<T: ?Trait1>(_: T) {}
23+
| ^^^^^^^
24+
25+
error: aborting due to 2 previous errors; 1 warning emitted
26+
27+
For more information about this error, try `rustc --explain E0658`.

‎tests/ui/maybe-bounds.stderr

+12-4
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,30 @@
1-
error: `?Trait` is not permitted in supertraits
1+
error[E0658]: `?Trait` is not permitted in supertraits
22
--> $DIR/maybe-bounds.rs:1:11
33
|
44
LL | trait Tr: ?Sized {}
55
| ^^^^^^
66
|
7-
= note: traits are `?Sized` by default
7+
= help: add `#![feature(allow_maybe_polarity)]` to the crate attributes to enable
8+
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
89

9-
error: `?Trait` is not permitted in trait object types
10+
error[E0658]: `?Trait` is not permitted in trait object types
1011
--> $DIR/maybe-bounds.rs:4:20
1112
|
1213
LL | type A1 = dyn Tr + (?Sized);
1314
| ^^^^^^^^
15+
|
16+
= help: add `#![feature(allow_maybe_polarity)]` to the crate attributes to enable
17+
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
1418

15-
error: `?Trait` is not permitted in trait object types
19+
error[E0658]: `?Trait` is not permitted in trait object types
1620
--> $DIR/maybe-bounds.rs:6:28
1721
|
1822
LL | type A2 = dyn for<'a> Tr + (?Sized);
1923
| ^^^^^^^^
24+
|
25+
= help: add `#![feature(allow_maybe_polarity)]` to the crate attributes to enable
26+
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
2027

2128
error: aborting due to 3 previous errors
2229

30+
For more information about this error, try `rustc --explain E0658`.

‎tests/ui/parser/trait-object-trait-parens.stderr

+14-4
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,29 @@
1-
error: `?Trait` is not permitted in trait object types
1+
error[E0658]: `?Trait` is not permitted in trait object types
22
--> $DIR/trait-object-trait-parens.rs:8:24
33
|
44
LL | let _: Box<(Obj) + (?Sized) + (for<'a> Trait<'a>)>;
55
| ^^^^^^^^
6+
|
7+
= help: add `#![feature(allow_maybe_polarity)]` to the crate attributes to enable
8+
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
69

7-
error: `?Trait` is not permitted in trait object types
10+
error[E0658]: `?Trait` is not permitted in trait object types
811
--> $DIR/trait-object-trait-parens.rs:13:16
912
|
1013
LL | let _: Box<?Sized + (for<'a> Trait<'a>) + (Obj)>;
1114
| ^^^^^^
15+
|
16+
= help: add `#![feature(allow_maybe_polarity)]` to the crate attributes to enable
17+
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
1218

13-
error: `?Trait` is not permitted in trait object types
19+
error[E0658]: `?Trait` is not permitted in trait object types
1420
--> $DIR/trait-object-trait-parens.rs:18:44
1521
|
1622
LL | let _: Box<for<'a> Trait<'a> + (Obj) + (?Sized)>;
1723
| ^^^^^^^^
24+
|
25+
= help: add `#![feature(allow_maybe_polarity)]` to the crate attributes to enable
26+
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
1827

1928
warning: trait objects without an explicit `dyn` are deprecated
2029
--> $DIR/trait-object-trait-parens.rs:8:16
@@ -91,4 +100,5 @@ LL | let _: Box<for<'a> Trait<'a> + (Obj) + (?Sized)>;
91100

92101
error: aborting due to 6 previous errors; 3 warnings emitted
93102

94-
For more information about this error, try `rustc --explain E0225`.
103+
Some errors have detailed explanations: E0225, E0658.
104+
For more information about an error, try `rustc --explain E0225`.
+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
//@ check-pass
2+
3+
#![feature(auto_traits)]
4+
#![feature(negative_impls)]
5+
#![feature(allow_maybe_polarity)]
6+
7+
trait Trait1 {}
8+
auto trait Trait2 {}
9+
10+
trait Trait3 : ?Trait1 {}
11+
fn foo(_: Box<(dyn Trait3 + ?Trait2)>) {}
12+
fn bar<T: ?Sized + ?Trait2 + ?Trait1>(_: &T) {}
13+
14+
struct S;
15+
impl !Trait2 for S {}
16+
impl Trait1 for S {}
17+
impl Trait3 for S {}
18+
19+
fn main() {
20+
foo(Box::new(S));
21+
bar(&S);
22+
}
+21-5
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,48 @@
1-
error: `?Trait` is not permitted in trait object types
1+
error[E0658]: `?Trait` is not permitted in trait object types
22
--> $DIR/maybe-bound.rs:5:15
33
|
44
LL | type _0 = dyn ?Sized + Foo;
55
| ^^^^^^
6+
|
7+
= help: add `#![feature(allow_maybe_polarity)]` to the crate attributes to enable
8+
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
69

7-
error: `?Trait` is not permitted in trait object types
10+
error[E0658]: `?Trait` is not permitted in trait object types
811
--> $DIR/maybe-bound.rs:8:21
912
|
1013
LL | type _1 = dyn Foo + ?Sized;
1114
| ^^^^^^
15+
|
16+
= help: add `#![feature(allow_maybe_polarity)]` to the crate attributes to enable
17+
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
1218

13-
error: `?Trait` is not permitted in trait object types
19+
error[E0658]: `?Trait` is not permitted in trait object types
1420
--> $DIR/maybe-bound.rs:11:21
1521
|
1622
LL | type _2 = dyn Foo + ?Sized + ?Sized;
1723
| ^^^^^^
24+
|
25+
= help: add `#![feature(allow_maybe_polarity)]` to the crate attributes to enable
26+
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
1827

19-
error: `?Trait` is not permitted in trait object types
28+
error[E0658]: `?Trait` is not permitted in trait object types
2029
--> $DIR/maybe-bound.rs:11:30
2130
|
2231
LL | type _2 = dyn Foo + ?Sized + ?Sized;
2332
| ^^^^^^
33+
|
34+
= help: add `#![feature(allow_maybe_polarity)]` to the crate attributes to enable
35+
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
2436

25-
error: `?Trait` is not permitted in trait object types
37+
error[E0658]: `?Trait` is not permitted in trait object types
2638
--> $DIR/maybe-bound.rs:15:15
2739
|
2840
LL | type _3 = dyn ?Sized + Foo;
2941
| ^^^^^^
42+
|
43+
= help: add `#![feature(allow_maybe_polarity)]` to the crate attributes to enable
44+
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
3045

3146
error: aborting due to 5 previous errors
3247

48+
For more information about this error, try `rustc --explain E0658`.
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
1-
error: `?Trait` is not permitted in trait object types
1+
error[E0658]: `?Trait` is not permitted in trait object types
22
--> $DIR/only-maybe-bound.rs:3:15
33
|
44
LL | type _0 = dyn ?Sized;
55
| ^^^^^^
6+
|
7+
= help: add `#![feature(allow_maybe_polarity)]` to the crate attributes to enable
8+
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
69

710
error[E0224]: at least one trait is required for an object type
811
--> $DIR/only-maybe-bound.rs:3:11
@@ -12,4 +15,5 @@ LL | type _0 = dyn ?Sized;
1215

1316
error: aborting due to 2 previous errors
1417

15-
For more information about this error, try `rustc --explain E0224`.
18+
Some errors have detailed explanations: E0224, E0658.
19+
For more information about an error, try `rustc --explain E0224`.

0 commit comments

Comments
 (0)
Please sign in to comment.