Skip to content

Commit d84587a

Browse files
committed
add polarity
1 parent 9afdb8d commit d84587a

File tree

40 files changed

+259
-115
lines changed

40 files changed

+259
-115
lines changed

compiler/rustc_ast_lowering/src/lib.rs

Lines changed: 13 additions & 15 deletions
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

Lines changed: 0 additions & 5 deletions
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

Lines changed: 1 addition & 9 deletions
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

Lines changed: 0 additions & 16 deletions
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

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use rustc_ast as ast;
2-
use rustc_ast::visit::{self, AssocCtxt, FnCtxt, FnKind, Visitor};
2+
use rustc_ast::visit::{self, AssocCtxt, BoundKind, FnCtxt, FnKind, Visitor};
33
use rustc_ast::{attr, AssocConstraint, AssocConstraintKind, NodeId};
44
use rustc_ast::{PatKind, RangeEnd};
55
use rustc_feature::{AttributeGate, BuiltinAttribute, Features, GateIssue, BUILTIN_ATTRIBUTE_MAP};
@@ -169,6 +169,25 @@ 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: BoundKind) {
173+
if let ast::GenericBound::Trait(poly, modifiers) = bound {
174+
let gate = |descr| {
175+
gate!(&self, more_maybe_bounds, poly.span, descr);
176+
};
177+
178+
match (ctxt, modifiers.polarity) {
179+
(BoundKind::TraitObject, ast::BoundPolarity::Maybe(_)) => {
180+
gate("`?Trait` is not permitted in trait object types");
181+
}
182+
(BoundKind::SuperTraits, ast::BoundPolarity::Maybe(_)) => {
183+
gate("`?Trait` is not permitted in supertraits");
184+
}
185+
_ => {}
186+
}
187+
}
188+
visit::walk_param_bound(self, bound);
189+
}
190+
172191
fn visit_attribute(&mut self, attr: &ast::Attribute) {
173192
let attr_info = attr.ident().and_then(|ident| BUILTIN_ATTRIBUTE_MAP.get(&ident.name));
174193
// Check feature gates for built-in attributes.

compiler/rustc_error_codes/src/error_codes/E0203.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1+
#### Note: this error code is no longer emitted by the compiler.
2+
13
Having multiple relaxed default bounds is unsupported.
24

3-
Erroneous code example:
5+
Previously erroneous code example:
46

5-
```compile_fail,E0203
7+
```compile_fail
68
struct Bad<T: ?Sized + ?Send>{
79
inner: T
810
}

compiler/rustc_error_codes/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -575,6 +575,7 @@ E0797: 0797,
575575
// E0190, // deprecated: can only cast a &-pointer to an &-object
576576
// E0194, // merged into E0403
577577
// E0196, // cannot determine a type for this closure
578+
// E0203 // replaced with a `more_maybe_bounds` feature gate
578579
// E0209, // builtin traits can only be implemented on structs or enums
579580
// E0213, // associated types are not accepted in this context
580581
// E0215, // angle-bracket notation is not stable with `Fn`

compiler/rustc_feature/src/unstable.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,8 @@ declare_features! (
207207
(unstable, lifetime_capture_rules_2024, "1.76.0", None),
208208
/// Allows `#[link(..., cfg(..))]`; perma-unstable per #37406
209209
(unstable, link_cfg, "1.14.0", None),
210+
/// Allows using `?Trait` trait bounds in more contexts.
211+
(internal, more_maybe_bounds, "CURRENT_RUSTC_VERSION", None),
210212
/// Allows the `multiple_supertrait_upcastable` lint.
211213
(unstable, multiple_supertrait_upcastable, "1.69.0", None),
212214
/// Allow negative trait bounds. This is an internal-only feature for testing the trait solver!

compiler/rustc_hir/src/hir.rs

Lines changed: 5 additions & 1 deletion
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

Lines changed: 3 additions & 1 deletion
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, _modifier) 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)),

0 commit comments

Comments
 (0)