Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 67c6ceb

Browse filesBrowse files
weswighamsandersn
andauthored
Reinterpret a type parameter constrained to any as an upper bound constraint (#29571)
* Reinterpret a type parameter constrained to any as an upper bound constraint * Use real constraqint in alias in test Co-authored-by: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com>
1 parent 3fdce8e commit 67c6ceb
Copy full SHA for 67c6ceb
Expand file treeCollapse file tree

21 files changed

+254
-36
lines changed

‎src/compiler/checker.ts

Copy file name to clipboardExpand all lines: src/compiler/checker.ts
+12-2Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11058,8 +11058,18 @@ namespace ts {
1105811058
}
1105911059
else {
1106011060
const constraintDeclaration = getConstraintDeclaration(typeParameter);
11061-
typeParameter.constraint = constraintDeclaration ? getTypeFromTypeNode(constraintDeclaration) :
11062-
getInferredTypeParameterConstraint(typeParameter) || noConstraintType;
11061+
if (!constraintDeclaration) {
11062+
typeParameter.constraint = getInferredTypeParameterConstraint(typeParameter) || noConstraintType;
11063+
}
11064+
else {
11065+
let type = getTypeFromTypeNode(constraintDeclaration);
11066+
if (type.flags & TypeFlags.Any && type !== errorType) { // Allow errorType to propegate to keep downstream errors suppressed
11067+
// use keyofConstraintType as the base constraint for mapped type key constraints (unknown isn;t assignable to that, but `any` was),
11068+
// use unknown otherwise
11069+
type = constraintDeclaration.parent.parent.kind === SyntaxKind.MappedType ? keyofConstraintType : unknownType;
11070+
}
11071+
typeParameter.constraint = type;
11072+
}
1106311073
}
1106411074
}
1106511075
return typeParameter.constraint === noConstraintType ? undefined : typeParameter.constraint;

‎tests/baselines/reference/contextuallyTypedParametersWithInitializers.types

Copy file name to clipboardExpand all lines: tests/baselines/reference/contextuallyTypedParametersWithInitializers.types
+2-2Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ declare function g1<T>(x: T): T;
162162
>x : T
163163

164164
declare function g2<T extends any>(x: T): T;
165-
>g2 : <T extends any>(x: T) => T
165+
>g2 : <T extends unknown>(x: T) => T
166166
>x : T
167167

168168
declare function g3<T extends unknown>(x: T): T;
@@ -192,7 +192,7 @@ g1((x = 1) => 0); // number
192192

193193
g2((x = 1) => 0); // number
194194
>g2((x = 1) => 0) : (x?: number) => 0
195-
>g2 : <T extends any>(x: T) => T
195+
>g2 : <T extends unknown>(x: T) => T
196196
>(x = 1) => 0 : (x?: number) => 0
197197
>x : number
198198
>1 : 1
+26Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
tests/cases/compiler/jsxExcessPropsAndAssignability.tsx(16,6): error TS2322: Type 'ComposedComponentProps & { myProp: number; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes<Component<WrapperComponentProps, any, any>> & Readonly<{ children?: ReactNode; }> & Readonly<WrapperComponentProps>'.
2+
Type 'ComposedComponentProps & { myProp: number; }' is not assignable to type 'Readonly<WrapperComponentProps>'.
3+
4+
5+
==== tests/cases/compiler/jsxExcessPropsAndAssignability.tsx (1 errors) ====
6+
/// <reference path="/.lib/react16.d.ts" />
7+
8+
import * as React from 'react';
9+
10+
const myHoc = <ComposedComponentProps extends any>(
11+
ComposedComponent: React.ComponentClass<ComposedComponentProps>,
12+
) => {
13+
type WrapperComponentProps = ComposedComponentProps & { myProp: string };
14+
const WrapperComponent: React.ComponentClass<WrapperComponentProps> = null as any;
15+
16+
const props: ComposedComponentProps = null as any;
17+
18+
// Expected no error, got none - good
19+
<WrapperComponent {...props} myProp={'1000000'} />;
20+
// Expected error, but got none - bad!
21+
<WrapperComponent {...props} myProp={1000000} />;
22+
~~~~~~~~~~~~~~~~
23+
!!! error TS2322: Type 'ComposedComponentProps & { myProp: number; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes<Component<WrapperComponentProps, any, any>> & Readonly<{ children?: ReactNode; }> & Readonly<WrapperComponentProps>'.
24+
!!! error TS2322: Type 'ComposedComponentProps & { myProp: number; }' is not assignable to type 'Readonly<WrapperComponentProps>'.
25+
};
26+
+44Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
//// [jsxExcessPropsAndAssignability.tsx]
2+
/// <reference path="/.lib/react16.d.ts" />
3+
4+
import * as React from 'react';
5+
6+
const myHoc = <ComposedComponentProps extends any>(
7+
ComposedComponent: React.ComponentClass<ComposedComponentProps>,
8+
) => {
9+
type WrapperComponentProps = ComposedComponentProps & { myProp: string };
10+
const WrapperComponent: React.ComponentClass<WrapperComponentProps> = null as any;
11+
12+
const props: ComposedComponentProps = null as any;
13+
14+
// Expected no error, got none - good
15+
<WrapperComponent {...props} myProp={'1000000'} />;
16+
// Expected error, but got none - bad!
17+
<WrapperComponent {...props} myProp={1000000} />;
18+
};
19+
20+
21+
//// [jsxExcessPropsAndAssignability.js]
22+
"use strict";
23+
/// <reference path="react16.d.ts" />
24+
var __assign = (this && this.__assign) || function () {
25+
__assign = Object.assign || function(t) {
26+
for (var s, i = 1, n = arguments.length; i < n; i++) {
27+
s = arguments[i];
28+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
29+
t[p] = s[p];
30+
}
31+
return t;
32+
};
33+
return __assign.apply(this, arguments);
34+
};
35+
exports.__esModule = true;
36+
var React = require("react");
37+
var myHoc = function (ComposedComponent) {
38+
var WrapperComponent = null;
39+
var props = null;
40+
// Expected no error, got none - good
41+
React.createElement(WrapperComponent, __assign({}, props, { myProp: '1000000' }));
42+
// Expected error, but got none - bad!
43+
React.createElement(WrapperComponent, __assign({}, props, { myProp: 1000000 }));
44+
};
+46Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
=== tests/cases/compiler/jsxExcessPropsAndAssignability.tsx ===
2+
/// <reference path="react16.d.ts" />
3+
4+
import * as React from 'react';
5+
>React : Symbol(React, Decl(jsxExcessPropsAndAssignability.tsx, 2, 6))
6+
7+
const myHoc = <ComposedComponentProps extends any>(
8+
>myHoc : Symbol(myHoc, Decl(jsxExcessPropsAndAssignability.tsx, 4, 5))
9+
>ComposedComponentProps : Symbol(ComposedComponentProps, Decl(jsxExcessPropsAndAssignability.tsx, 4, 15))
10+
11+
ComposedComponent: React.ComponentClass<ComposedComponentProps>,
12+
>ComposedComponent : Symbol(ComposedComponent, Decl(jsxExcessPropsAndAssignability.tsx, 4, 51))
13+
>React : Symbol(React, Decl(jsxExcessPropsAndAssignability.tsx, 2, 6))
14+
>ComponentClass : Symbol(React.ComponentClass, Decl(react16.d.ts, 421, 9))
15+
>ComposedComponentProps : Symbol(ComposedComponentProps, Decl(jsxExcessPropsAndAssignability.tsx, 4, 15))
16+
17+
) => {
18+
type WrapperComponentProps = ComposedComponentProps & { myProp: string };
19+
>WrapperComponentProps : Symbol(WrapperComponentProps, Decl(jsxExcessPropsAndAssignability.tsx, 6, 6))
20+
>ComposedComponentProps : Symbol(ComposedComponentProps, Decl(jsxExcessPropsAndAssignability.tsx, 4, 15))
21+
>myProp : Symbol(myProp, Decl(jsxExcessPropsAndAssignability.tsx, 7, 59))
22+
23+
const WrapperComponent: React.ComponentClass<WrapperComponentProps> = null as any;
24+
>WrapperComponent : Symbol(WrapperComponent, Decl(jsxExcessPropsAndAssignability.tsx, 8, 9))
25+
>React : Symbol(React, Decl(jsxExcessPropsAndAssignability.tsx, 2, 6))
26+
>ComponentClass : Symbol(React.ComponentClass, Decl(react16.d.ts, 421, 9))
27+
>WrapperComponentProps : Symbol(WrapperComponentProps, Decl(jsxExcessPropsAndAssignability.tsx, 6, 6))
28+
29+
const props: ComposedComponentProps = null as any;
30+
>props : Symbol(props, Decl(jsxExcessPropsAndAssignability.tsx, 10, 9))
31+
>ComposedComponentProps : Symbol(ComposedComponentProps, Decl(jsxExcessPropsAndAssignability.tsx, 4, 15))
32+
33+
// Expected no error, got none - good
34+
<WrapperComponent {...props} myProp={'1000000'} />;
35+
>WrapperComponent : Symbol(WrapperComponent, Decl(jsxExcessPropsAndAssignability.tsx, 8, 9))
36+
>props : Symbol(props, Decl(jsxExcessPropsAndAssignability.tsx, 10, 9))
37+
>myProp : Symbol(myProp, Decl(jsxExcessPropsAndAssignability.tsx, 13, 32))
38+
39+
// Expected error, but got none - bad!
40+
<WrapperComponent {...props} myProp={1000000} />;
41+
>WrapperComponent : Symbol(WrapperComponent, Decl(jsxExcessPropsAndAssignability.tsx, 8, 9))
42+
>props : Symbol(props, Decl(jsxExcessPropsAndAssignability.tsx, 10, 9))
43+
>myProp : Symbol(myProp, Decl(jsxExcessPropsAndAssignability.tsx, 15, 32))
44+
45+
};
46+
+48Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
=== tests/cases/compiler/jsxExcessPropsAndAssignability.tsx ===
2+
/// <reference path="react16.d.ts" />
3+
4+
import * as React from 'react';
5+
>React : typeof React
6+
7+
const myHoc = <ComposedComponentProps extends any>(
8+
>myHoc : <ComposedComponentProps extends unknown>(ComposedComponent: React.ComponentClass<ComposedComponentProps, any>) => void
9+
><ComposedComponentProps extends any>( ComposedComponent: React.ComponentClass<ComposedComponentProps>,) => { type WrapperComponentProps = ComposedComponentProps & { myProp: string }; const WrapperComponent: React.ComponentClass<WrapperComponentProps> = null as any; const props: ComposedComponentProps = null as any; // Expected no error, got none - good <WrapperComponent {...props} myProp={'1000000'} />; // Expected error, but got none - bad! <WrapperComponent {...props} myProp={1000000} />;} : <ComposedComponentProps extends unknown>(ComposedComponent: React.ComponentClass<ComposedComponentProps, any>) => void
10+
11+
ComposedComponent: React.ComponentClass<ComposedComponentProps>,
12+
>ComposedComponent : React.ComponentClass<ComposedComponentProps, any>
13+
>React : any
14+
15+
) => {
16+
type WrapperComponentProps = ComposedComponentProps & { myProp: string };
17+
>WrapperComponentProps : ComposedComponentProps & { myProp: string; }
18+
>myProp : string
19+
20+
const WrapperComponent: React.ComponentClass<WrapperComponentProps> = null as any;
21+
>WrapperComponent : React.ComponentClass<ComposedComponentProps & { myProp: string; }, any>
22+
>React : any
23+
>null as any : any
24+
>null : null
25+
26+
const props: ComposedComponentProps = null as any;
27+
>props : ComposedComponentProps
28+
>null as any : any
29+
>null : null
30+
31+
// Expected no error, got none - good
32+
<WrapperComponent {...props} myProp={'1000000'} />;
33+
><WrapperComponent {...props} myProp={'1000000'} /> : JSX.Element
34+
>WrapperComponent : React.ComponentClass<ComposedComponentProps & { myProp: string; }, any>
35+
>props : ComposedComponentProps
36+
>myProp : "1000000"
37+
>'1000000' : "1000000"
38+
39+
// Expected error, but got none - bad!
40+
<WrapperComponent {...props} myProp={1000000} />;
41+
><WrapperComponent {...props} myProp={1000000} /> : JSX.Element
42+
>WrapperComponent : React.ComponentClass<ComposedComponentProps & { myProp: string; }, any>
43+
>props : ComposedComponentProps
44+
>myProp : number
45+
>1000000 : 1000000
46+
47+
};
48+

‎tests/baselines/reference/mappedTypeWithAny.types

Copy file name to clipboardExpand all lines: tests/baselines/reference/mappedTypeWithAny.types
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ declare let x0: keyof any;
1010
>x0 : string | number | symbol
1111

1212
declare let x1: { [P in any]: Item };
13-
>x1 : { [x: string]: Item; }
13+
>x1 : { [x: string]: Item; [x: number]: Item; }
1414

1515
declare let x2: { [P in string]: Item };
1616
>x2 : { [x: string]: Item; }

‎tests/baselines/reference/typeArgumentInferenceWithConstraints.types

Copy file name to clipboardExpand all lines: tests/baselines/reference/typeArgumentInferenceWithConstraints.types
+8-8Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -357,7 +357,7 @@ x<string, string, string>(null, null, null); // Error
357357

358358
// Generic call with multiple parameters of generic type passed arguments with no best common type
359359
function someGenerics9<T extends any>(a: T, b: T, c: T): T {
360-
>someGenerics9 : <T extends any>(a: T, b: T, c: T) => T
360+
>someGenerics9 : <T extends unknown>(a: T, b: T, c: T) => T
361361
>a : T
362362
>b : T
363363
>c : T
@@ -368,7 +368,7 @@ function someGenerics9<T extends any>(a: T, b: T, c: T): T {
368368
var a9a = someGenerics9('', 0, []);
369369
>a9a : string
370370
>someGenerics9('', 0, []) : ""
371-
>someGenerics9 : <T extends any>(a: T, b: T, c: T) => T
371+
>someGenerics9 : <T extends unknown>(a: T, b: T, c: T) => T
372372
>'' : ""
373373
>0 : 0
374374
>[] : undefined[]
@@ -379,7 +379,7 @@ var a9a: {};
379379
var a9b = someGenerics9<{ a?: number; b?: string; }>({ a: 0 }, { b: '' }, null);
380380
>a9b : { a?: number; b?: string; }
381381
>someGenerics9<{ a?: number; b?: string; }>({ a: 0 }, { b: '' }, null) : { a?: number; b?: string; }
382-
>someGenerics9 : <T extends any>(a: T, b: T, c: T) => T
382+
>someGenerics9 : <T extends unknown>(a: T, b: T, c: T) => T
383383
>a : number
384384
>b : string
385385
>{ a: 0 } : { a: number; }
@@ -413,7 +413,7 @@ interface A92 {
413413
var a9e = someGenerics9(undefined, { x: 6, z: window }, { x: 6, y: '' });
414414
>a9e : { x: number; z: Window & typeof globalThis; y?: undefined; } | { x: number; y: string; z?: undefined; }
415415
>someGenerics9(undefined, { x: 6, z: window }, { x: 6, y: '' }) : { x: number; z: Window & typeof globalThis; y?: undefined; } | { x: number; y: string; z?: undefined; }
416-
>someGenerics9 : <T extends any>(a: T, b: T, c: T) => T
416+
>someGenerics9 : <T extends unknown>(a: T, b: T, c: T) => T
417417
>undefined : undefined
418418
>{ x: 6, z: window } : { x: number; z: Window & typeof globalThis; }
419419
>x : number
@@ -432,7 +432,7 @@ var a9e: {};
432432
var a9f = someGenerics9<A92>(undefined, { x: 6, z: window }, { x: 6, y: '' });
433433
>a9f : A92
434434
>someGenerics9<A92>(undefined, { x: 6, z: window }, { x: 6, y: '' }) : A92
435-
>someGenerics9 : <T extends any>(a: T, b: T, c: T) => T
435+
>someGenerics9 : <T extends unknown>(a: T, b: T, c: T) => T
436436
>undefined : undefined
437437
>{ x: 6, z: window } : { x: number; z: Window & typeof globalThis; }
438438
>x : number
@@ -452,7 +452,7 @@ var a9f: A92;
452452
var a9d = someGenerics9({ x: 3 }, { x: 6 }, { x: 6 });
453453
>a9d : { x: number; }
454454
>someGenerics9({ x: 3 }, { x: 6 }, { x: 6 }) : { x: number; }
455-
>someGenerics9 : <T extends any>(a: T, b: T, c: T) => T
455+
>someGenerics9 : <T extends unknown>(a: T, b: T, c: T) => T
456456
>{ x: 3 } : { x: number; }
457457
>x : number
458458
>3 : 3
@@ -474,7 +474,7 @@ var anyVar: any;
474474
var a = someGenerics9(7, anyVar, 4);
475475
>a : any
476476
>someGenerics9(7, anyVar, 4) : any
477-
>someGenerics9 : <T extends any>(a: T, b: T, c: T) => T
477+
>someGenerics9 : <T extends unknown>(a: T, b: T, c: T) => T
478478
>7 : 7
479479
>anyVar : any
480480
>4 : 4
@@ -486,7 +486,7 @@ var a: any;
486486
var arr = someGenerics9([], null, undefined);
487487
>arr : any[]
488488
>someGenerics9([], null, undefined) : any[]
489-
>someGenerics9 : <T extends any>(a: T, b: T, c: T) => T
489+
>someGenerics9 : <T extends unknown>(a: T, b: T, c: T) => T
490490
>[] : undefined[]
491491
>null : null
492492
>undefined : undefined

‎tests/baselines/reference/typeParameterConstraints1.types

Copy file name to clipboardExpand all lines: tests/baselines/reference/typeParameterConstraints1.types
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
=== tests/cases/compiler/typeParameterConstraints1.ts ===
22
function foo1<T extends any>(test: T) { }
3-
>foo1 : <T extends any>(test: T) => void
3+
>foo1 : <T extends unknown>(test: T) => void
44
>test : T
55

66
function foo2<T extends number>(test: T) { }

‎tests/baselines/reference/typeParameterExplicitlyExtendsAny.errors.txt

Copy file name to clipboardExpand all lines: tests/baselines/reference/typeParameterExplicitlyExtendsAny.errors.txt
+20-1Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,14 @@
11
tests/cases/compiler/typeParameterExplicitlyExtendsAny.ts(3,7): error TS2339: Property 'blah' does not exist on type 'T'.
2+
tests/cases/compiler/typeParameterExplicitlyExtendsAny.ts(9,7): error TS2339: Property 'blah' does not exist on type 'T'.
3+
tests/cases/compiler/typeParameterExplicitlyExtendsAny.ts(14,7): error TS2339: Property 'children' does not exist on type 'T'.
4+
tests/cases/compiler/typeParameterExplicitlyExtendsAny.ts(15,5): error TS2349: This expression is not callable.
5+
Type '{}' has no call signatures.
6+
tests/cases/compiler/typeParameterExplicitlyExtendsAny.ts(16,9): error TS2351: This expression is not constructable.
7+
Type '{}' has no construct signatures.
8+
tests/cases/compiler/typeParameterExplicitlyExtendsAny.ts(30,14): error TS2339: Property 'children' does not exist on type 'T'.
29

310

4-
==== tests/cases/compiler/typeParameterExplicitlyExtendsAny.ts (1 errors) ====
11+
==== tests/cases/compiler/typeParameterExplicitlyExtendsAny.ts (6 errors) ====
512
function fee<T>() {
613
var t: T;
714
t.blah; // Error
@@ -13,13 +20,23 @@ tests/cases/compiler/typeParameterExplicitlyExtendsAny.ts(3,7): error TS2339: Pr
1320
function fee2<T extends any>() {
1421
var t: T;
1522
t.blah; // ok
23+
~~~~
24+
!!! error TS2339: Property 'blah' does not exist on type 'T'.
1625
t.toString; // ok
1726
}
1827

1928
function f<T extends any>(x: T) {
2029
x.children;
30+
~~~~~~~~
31+
!!! error TS2339: Property 'children' does not exist on type 'T'.
2132
x();
33+
~
34+
!!! error TS2349: This expression is not callable.
35+
!!! error TS2349: Type '{}' has no call signatures.
2236
new x();
37+
~
38+
!!! error TS2351: This expression is not constructable.
39+
!!! error TS2351: Type '{}' has no construct signatures.
2340
x[100];
2441
x['hello'];
2542
}
@@ -34,6 +51,8 @@ tests/cases/compiler/typeParameterExplicitlyExtendsAny.ts(3,7): error TS2339: Pr
3451
public static displayTree1<T extends Tree<any>>(tree: T) {
3552
// error "Property 'children' does not exist on type 'T'"
3653
tree.children;
54+
~~~~~~~~
55+
!!! error TS2339: Property 'children' does not exist on type 'T'.
3756
}
3857
}
3958

‎tests/baselines/reference/typeParameterExplicitlyExtendsAny.symbols

Copy file name to clipboardExpand all lines: tests/baselines/reference/typeParameterExplicitlyExtendsAny.symbols
+2Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,9 @@ function fee2<T extends any>() {
2828
>t : Symbol(t, Decl(typeParameterExplicitlyExtendsAny.ts, 7, 7))
2929

3030
t.toString; // ok
31+
>t.toString : Symbol(Object.toString, Decl(lib.es5.d.ts, --, --))
3132
>t : Symbol(t, Decl(typeParameterExplicitlyExtendsAny.ts, 7, 7))
33+
>toString : Symbol(Object.toString, Decl(lib.es5.d.ts, --, --))
3234
}
3335

3436
function f<T extends any>(x: T) {

‎tests/baselines/reference/typeParameterExplicitlyExtendsAny.types

Copy file name to clipboardExpand all lines: tests/baselines/reference/typeParameterExplicitlyExtendsAny.types
+5-5Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ function fee<T>() {
1717
}
1818

1919
function fee2<T extends any>() {
20-
>fee2 : <T extends any>() => void
20+
>fee2 : <T extends unknown>() => void
2121

2222
var t: T;
2323
>t : T
@@ -28,13 +28,13 @@ function fee2<T extends any>() {
2828
>blah : any
2929

3030
t.toString; // ok
31-
>t.toString : any
31+
>t.toString : () => string
3232
>t : T
33-
>toString : any
33+
>toString : () => string
3434
}
3535

3636
function f<T extends any>(x: T) {
37-
>f : <T extends any>(x: T) => void
37+
>f : <T extends unknown>(x: T) => void
3838
>x : T
3939

4040
x.children;
@@ -74,7 +74,7 @@ class MyClass {
7474
>MyClass : MyClass
7575

7676
public static displayTree1<T extends Tree<any>>(tree: T) {
77-
>displayTree1 : <T extends any>(tree: T) => void
77+
>displayTree1 : <T extends unknown>(tree: T) => void
7878
>tree : T
7979

8080
// error "Property 'children' does not exist on type 'T'"

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.